diff --git a/.editorconfig b/.editorconfig
index 7400f6df98b17..7ff7c2c3d8ba9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -61,6 +61,9 @@ dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
+# Whitespace options
+dotnet_style_allow_multiple_blank_lines_experimental = false
+
# Non-private static fields are PascalCase
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non_private_static_fields
@@ -182,6 +185,11 @@ csharp_indent_case_contents_when_block = true
csharp_indent_switch_labels = true
csharp_indent_labels = flush_left
+# Whitespace options
+csharp_style_allow_embedded_statements_on_same_line_experimental = false
+csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
+csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
+
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
@@ -233,6 +241,10 @@ csharp_prefer_braces = true:silent
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true
+# Currently only enabled for C# due to crash in VB analyzer. VB can be enabled once
+# https://github.com/dotnet/roslyn/pull/54259 has been published.
+dotnet_style_allow_statement_immediately_after_block_experimental = false
+
[src/CodeStyle/**.{cs,vb}]
# warning RS0005: Do not use generic CodeAction.Create to create CodeAction
dotnet_diagnostic.RS0005.severity = none
@@ -272,6 +284,21 @@ csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = true:warning
+# dotnet_style_allow_multiple_blank_lines_experimental
+dotnet_diagnostic.IDE2000.severity = warning
+
+# csharp_style_allow_embedded_statements_on_same_line_experimental
+dotnet_diagnostic.IDE2001.severity = warning
+
+# csharp_style_allow_blank_lines_between_consecutive_braces_experimental
+dotnet_diagnostic.IDE2002.severity = warning
+
+# dotnet_style_allow_statement_immediately_after_block_experimental
+dotnet_diagnostic.IDE2003.severity = warning
+
+# csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental
+dotnet_diagnostic.IDE2004.severity = warning
+
[src/{VisualStudio}/**/*.{cs,vb}]
# CA1822: Make member static
# Not enforced as a build 'warning' for 'VisualStudio' layer due to large number of false positives from https://github.com/dotnet/roslyn-analyzers/issues/3857 and https://github.com/dotnet/roslyn-analyzers/issues/3858
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
new file mode 100644
index 0000000000000..efdda18ee9aca
--- /dev/null
+++ b/.git-blame-ignore-revs
@@ -0,0 +1,2 @@
+# Dotnet-format -w Roslyn.sln
+abce41d282ac631be5217140f1bd46d0e250ad02
diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml
index f31edeb4d3bd8..f16df6c5ce694 100644
--- a/azure-pipelines-official.yml
+++ b/azure-pipelines-official.yml
@@ -2,14 +2,25 @@ resources:
- repo: self
clean: true
-# 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: real
-# SkipTests: false
-# SkipApplyOptimizationData: false
-# IbcDrop: 'default'
-# PRNumber: 'default'
+parameters:
+- name: IbcDrop
+ type: string
+ default: default
+
+- name: SignType
+ default: real
+ type: string
+ values:
+ - real
+ - test
+
+- name: SkipApplyOptimizationData
+ type: boolean
+ default: false
+
+- name: SkipTests
+ type: boolean
+ default: true
# The variables `_DotNetArtifactsCategory` and `_DotNetValidationArtifactsCategory` are required for proper publishing of build artifacts. See https://github.com/dotnet/roslyn/pull/38259
variables:
@@ -20,46 +31,36 @@ variables:
- group: DotNet-Roslyn-SDLValidation-Params
# 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.
- # Get $AccessToken-dotnet-build-bot-public-repo from DotNet-GitHub-Versions-Repo-Write
- - ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- - group: DotNet-GitHub-Versions-Repo-Write
- - name: _DevDivDropAccessToken
- value: $(System.AccessToken)
- # If the pipeline is running in dnceng:
# Get access token with $dn-bot-devdiv-drop-rw-code-rw and dn-bot-dnceng-build-rw-code-rw from DotNet-VSTS-Infra-Access
# Get $dotnetfeed-storage-access-key-1 from DotNet-Blob-Feed
# Get $microsoft-symbol-server-pat and $symweb-symbol-server-pat from DotNet-Symbol-Server-Pats
# Get $AccessToken-dotnet-build-bot-public-repo from DotNet-Versions-Publish
- - ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- - group: DotNet-Blob-Feed
- - group: DotNet-Symbol-Server-Pats
- - group: DotNet-Versions-Publish
- - group: DotNet-VSTS-Infra-Access
- - group: DotNet-DevDiv-Insertion-Workflow-Variables
- - name: _DevDivDropAccessToken
- value: $(dn-bot-devdiv-drop-rw-code-rw)
+ - group: DotNet-Blob-Feed
+ - group: DotNet-Symbol-Server-Pats
+ - group: DotNet-Versions-Publish
+ - group: DotNet-VSTS-Infra-Access
+ - group: DotNet-DevDiv-Insertion-Workflow-Variables
+ - name: _DevDivDropAccessToken
+ value: $(dn-bot-devdiv-drop-rw-code-rw)
+ - group: ManagedLanguageSecrets
+
+ - name: BuildConfiguration
+ value: release
+ - name: Roslyn.GitHubEmail
+ value: dotnet-build-bot@microsoft.com
+ - name: Roslyn.GitHubToken
+ value: $(AccessToken-dotnet-build-bot-public-repo)
+ - name: Roslyn.GitHubUserName
+ value: dotnet-build-bot
+
+ - name: Insertion.InsertToolset
+ value: true
+ - name: Insertion.CreateDraftPR
+ value: true
+ - name: Insertion.TitlePrefix
+ value: '[Auto Insertion]'
stages:
-- stage: setup
- displayName: Build Setup
-
- jobs:
- - job: SetBuildNumber
- pool:
- vmImage: vs2017-win2016
- steps:
- # Make sure our two pipelines generate builds with distinct build numbers to avoid confliction.
- # i.e. DevDiv builds will have even rev# whereas dnceng builds will be odd.
- - task: PowerShell@2
- displayName: Update BuildNumber
- inputs:
- filePath: 'eng\update-build-number.ps1'
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- arguments: '-buildNumber $(Build.BuildNumber) -oddOrEven even'
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- arguments: '-buildNumber $(Build.BuildNumber) -oddOrEven odd'
- condition: eq(variables['System.JobAttempt'], '1')
- stage: build
displayName: Build and Test
@@ -76,17 +77,9 @@ stages:
- job: OfficialBuild
displayName: Official Build
timeoutInMinutes: 360
- # Conditionally set build pool so we can share this YAML when building with different pipeline (devdiv vs dnceng)
pool:
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- name: VSEngSS-MicroBuild2017
- demands:
- - msbuild
- - visualstudio
- - DotNetFramework
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- name: NetCoreInternal-Pool
- queue: BuildPool.Server.Amd64.VS2017
+ name: NetCoreInternal-Pool
+ queue: BuildPool.Server.Amd64.VS2017
steps:
- powershell: Write-Host "##vso[task.setvariable variable=SourceBranchName]$('$(Build.SourceBranch)'.Substring('refs/heads/'.Length))"
@@ -98,23 +91,7 @@ stages:
inputs:
type: 'Build'
tags: 'OfficialBuild'
- condition: and(succeeded(), endsWith(variables['SourceBranchName'], '-vs-deps'), eq(variables['PRNumber'], 'default'))
-
- - task: tagBuildOrRelease@0
- displayName: Tag PR validation build
- inputs:
- type: 'Build'
- tags: |
- PRValidationBuild
- PRNumber:$(PRNumber)
- condition: and(succeeded(), ne(variables['PRNumber'], 'default'))
-
- - task: PowerShell@2
- displayName: Setup branch for insertion validation
- inputs:
- filePath: 'eng\setup-pr-validation.ps1'
- arguments: '-sourceBranchName $(SourceBranchName) -prNumber $(PRNumber)'
- condition: and(succeeded(), ne(variables['PRNumber'], 'default'))
+ condition: and(succeeded(), endsWith(variables['SourceBranchName'], '-vs-deps'))
- task: tagBuildOrRelease@0
displayName: Tag main validation build
@@ -128,8 +105,7 @@ stages:
displayName: Merge main-vs-deps into source branch
inputs:
filePath: 'scripts\merge-vs-deps.ps1'
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- arguments: '-accessToken $(dn-bot-dnceng-build-rw-code-rw)'
+ arguments: '-accessToken $(dn-bot-dnceng-build-rw-code-rw)'
condition: and(succeeded(), eq(variables['SourceBranchName'], 'main'))
- powershell: Write-Host "##vso[task.setvariable variable=VisualStudio.DropName]Products/$(System.TeamProject)/$(Build.Repository.Name)/$(SourceBranchName)/$(Build.BuildNumber)"
@@ -142,20 +118,15 @@ stages:
# Authenticate with service connections to be able to publish packages to external nuget feeds.
- task: NuGetAuthenticate@0
inputs:
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk, devdiv/engineering
+ nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk, devdiv/engineering
- # Needed because the dnceng image we build on fails the next task without it
+ # 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)'
- installationPath: '$(Build.SourcesDirectory)/.dotnet'
- condition: eq(variables['System.TeamProject'], 'internal')
# Needed to restore the Microsoft.DevDiv.Optimization.Data.PowerShell package
- task: NuGetCommand@2
@@ -171,9 +142,7 @@ stages:
inputs:
signType: $(SignType)
zipSources: false
- # If running in dnceng, we need to use a feed different from default
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
+ feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json
condition: and(succeeded(), in(variables['SignType'], 'test', 'real'))
- task: PowerShell@2
@@ -212,7 +181,7 @@ stages:
inputs:
filePath: 'eng\publish-assets.ps1'
arguments: '-configuration $(BuildConfiguration) -branchName "$(SourceBranchName)"'
- condition: and(succeeded(), eq(variables['PRNumber'], 'default'))
+ condition: succeeded()
# Publish OptProf configuration files
# The env variable is required to enable cross account access using PAT (dnceng -> devdiv)
@@ -282,12 +251,8 @@ stages:
command: push
packagesToPush: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\DevDivPackages\**\*.nupkg'
allowPackageConflicts: true
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- feedsToUse: config
- publishVstsFeed: '97a41293-2972-4f48-8c0e-05493ae82010'
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- nuGetFeedType: external
- publishFeedCredentials: 'DevDiv - VS package feed'
+ nuGetFeedType: external
+ publishFeedCredentials: 'DevDiv - VS package feed'
condition: succeeded()
# Publish an artifact that the RoslynInsertionTool is able to find by its name.
@@ -325,25 +290,89 @@ stages:
publishUsingPipelines: true
dependsOn:
- OfficialBuild
- ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}:
- queue:
- name: Hosted VS2017
- ${{ if eq(variables['System.TeamProject'], 'internal') }}:
- pool:
- vmImage: vs2017-win2016
-
-# We need to skip post-build stages for PR validation build, but it can only be identified by
-# the runtime variable 'PRNumber', thus this dummy stage. Also the dummy job is required
-# otherwise AzDO would just repeat jobs from previous stage.
-- stage: SetValidateDependency
- displayName: Setup the dependency for post-build stages
- condition: and(succeeded(), eq(variables['PRNumber'], 'default'))
+ pool:
+ vmImage: vs2017-win2016
+
+- stage: insert
+ dependsOn:
+ - build
+ - publish_using_darc
+ displayName: Insert to VS
+
jobs:
- - job: Log
- displayName: Log
+ - job: insert
+ displayName: Insert to VS
+ pool:
+ vmImage: windows-2019
steps:
- - powershell: Write-Host "Setup the dependency for post-build stages."
- displayName: Log
+ - checkout: none
+
+ - task: NuGetCommand@2
+ displayName: 'Install RIT from Azure Artifacts'
+ inputs:
+ command: custom
+ arguments: 'install RoslynTools.VisualStudioInsertionTool -PreRelease -Source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json'
+
+ - powershell: |
+ $response = Invoke-RestMethod -Headers @{Authorization = "Bearer $(System.AccessToken)"} "https://dev.azure.com/dnceng/internal/_apis/git/repositories/dotnet-roslyn/items?path=eng/config/PublishData.json&api-version=6.0"
+ $branchName = "$(Build.SourceBranch)".Substring("refs/heads/".Length)
+ $branchData = $response.branches.$branchName
+ if (!$branchData)
+ {
+ Write-Host "No PublishData found for branch '$branchName'. Using PublishData for branch 'main'."
+ $branchData = $response.branches.main
+ }
+ if ($null -ne $branchData.insertionCreateDraftPR)
+ {
+ Write-Host "##vso[task.setvariable variable=Insertion.CreateDraftPR]$($branchData.insertionCreateDraftPR)"
+ }
+ if ($null -ne $branchData.insertionTitlePrefix)
+ {
+ Write-Host "##vso[task.setvariable variable=Insertion.TitlePrefix]$($branchData.insertionTitlePrefix)"
+ }
+ if ($null -ne $branchData.insertToolset)
+ {
+ Write-Host "##vso[task.setvariable variable=Insertion.InsertToolset]$($branchData.insertToolset)"
+ }
+
+ Write-Host "##vso[task.setvariable variable=Insertion.AutoComplete]$(-not $branchData.insertionCreateDraftPR)"
+ Write-Host "##vso[task.setvariable variable=ComponentBranchName]$branchName"
+ Write-Host "##vso[task.setvariable variable=VSBranchName]$($branchData.vsBranch)"
+ displayName: Set Insertion Variables
+
+ - powershell: |
+ mv RoslynTools.VisualStudioInsertionTool.* RIT
+ .\RIT\tools\OneOffInsertion.ps1 `
+ -autoComplete "$(Insertion.AutoComplete)" `
+ -buildQueueName "$(Build.DefinitionName)" `
+ -cherryPick "(default)" `
+ -clientId "$(ClientId)" `
+ -clientSecret "$(ClientSecret)" `
+ -componentAzdoUri "$(System.CollectionUri)" `
+ -componentBranchName "$(ComponentBranchName)" `
+ -componentGitHubRepoName "dotnet/roslyn" `
+ -componentName "Roslyn" `
+ -componentProjectName "internal" `
+ -createDraftPR "$(Insertion.CreateDraftPR)" `
+ -defaultValueSentinel "(default)" `
+ -dropPath "(default)" `
+ -insertCore "(default)" `
+ -insertDevDiv "(default)" `
+ -insertionCount "1" `
+ -insertToolset "$(Insertion.InsertToolset)" `
+ -titlePrefix "$(Insertion.TitlePrefix)" `
+ -queueValidation "true" `
+ -requiredValueSentinel "REQUIRED" `
+ -reviewerGUID "6c25b447-1d90-4840-8fde-d8b22cb8733e" `
+ -specificBuild "$(Build.BuildNumber)" `
+ -updateAssemblyVersions "(default)" `
+ -updateCoreXTLibraries "(default)" `
+ -visualStudioBranchName "$(VSBranchName)" `
+ -writePullRequest "prid.txt" `
+ displayName: 'Run OneOffInsertion.ps1'
+
+ - script: 'echo. && echo. && type "prid.txt" && echo. && echo.'
+ displayName: 'Report PR URL'
- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- template: eng\common\templates\post-build\post-build.yml
@@ -353,12 +382,6 @@ stages:
# https://github.com/dotnet/arcade/issues/2871 is resolved.
enableSymbolValidation: false
enableSourceLinkValidation: false
- # It's important that post-build stages are depends on 'SetValidateDependency' stage instead of 'build',
- # since we don't want to publish validation build.
- validateDependsOn:
- - SetValidateDependency
- dependsOn:
- - SetValidateDependency
# Enable SDL validation, passing through values from the 'DotNet-Roslyn-SDLValidation-Params' group.
SDLValidationParameters:
enable: true
diff --git a/azure-pipelines-pr-validation.yml b/azure-pipelines-pr-validation.yml
new file mode 100644
index 0000000000000..7f1078fdc5928
--- /dev/null
+++ b/azure-pipelines-pr-validation.yml
@@ -0,0 +1,196 @@
+resources:
+- repo: self
+ clean: true
+
+# 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'
+
+parameters:
+- name: PRNumber
+ type: number
+- name: CommitSHA
+ type: string
+
+# The variables `_DotNetArtifactsCategory` and `_DotNetValidationArtifactsCategory` are required for proper publishing of build artifacts. See https://github.com/dotnet/roslyn/pull/38259
+variables:
+ - name: _DotNetArtifactsCategory
+ value: .NETCore
+ - name: _DotNetValidationArtifactsCategory
+ value: .NETCoreValidation
+ - group: DotNet-Roslyn-SDLValidation-Params
+
+ # 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.
+ # Get $AccessToken-dotnet-build-bot-public-repo from DotNet-GitHub-Versions-Repo-Write
+ - group: DotNet-GitHub-Versions-Repo-Write
+ - name: _DevDivDropAccessToken
+ value: $(System.AccessToken)
+
+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
+ pool:
+ name: VSEngSS-MicroBuild2017
+ 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: tagBuildOrRelease@0
+ displayName: Tag PR validation build
+ inputs:
+ type: 'Build'
+ tags: |
+ PRValidationBuild
+ PRNumber:${{ parameters.PRNumber }}
+ CommitSHA:${{ parameters.CommitSHA }}
+ 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@0
+ inputs:
+ nuGetServiceConnections: azure-public/vs-impl, azure-public/vssdk
+
+ # 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@2
+ 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
+ -restore
+ -build
+ -pack
+ -sign
+ -publish
+ -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:PreReleaseVersionLabel=pr-validation
+ 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()
diff --git a/azure-pipelines-richnav.yml b/azure-pipelines-richnav.yml
index 6652eb3757fae..d327060f6c65e 100644
--- a/azure-pipelines-richnav.yml
+++ b/azure-pipelines-richnav.yml
@@ -1,6 +1,20 @@
+# Branches that trigger a build on commit
trigger:
- main
+- main-vs-deps
+- release/*
+- features/*
+- demos/*
+
+# Branches that trigger builds on PR
pr: none
+# Temporarily disabling richnav job on PRs
+# pr:
+# - main
+# - main-vs-deps
+# - release/*
+# - features/*
+# - demos/*
jobs:
- job: RichCodeNav_Indexing
diff --git a/docs/Language Feature Status.md b/docs/Language Feature Status.md
index 5a28acb0fe789..768a966e61f4e 100644
--- a/docs/Language Feature Status.md
+++ b/docs/Language Feature Status.md
@@ -10,27 +10,34 @@ efforts behind them.
| Feature | Branch | State | Developer | Reviewer | LDM Champ |
| ------- | ------ | ----- | --------- | -------- | --------- |
-| [Record structs](https://github.com/dotnet/csharplang/issues/4334) | [record-structs](https://github.com/dotnet/roslyn/tree/features/record-structs) | [In Progress](https://github.com/dotnet/roslyn/issues/51199) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) |
-| [Global Using Directive](https://github.com/dotnet/csharplang/issues/3428) | [GlobalUsingDirective](https://github.com/dotnet/roslyn/tree/features/GlobalUsingDirective) | [In Progress](https://github.com/dotnet/roslyn/issues/51307) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [cston](https://github.com/cston) | [AlekseyTs](https://github.com/AlekseyTs) |
| [Static Abstract Members In Interfaces](https://github.com/dotnet/csharplang/issues/4436) | [StaticAbstractMembersInInterfaces](https://github.com/dotnet/roslyn/tree/features/StaticAbstractMembersInInterfaces) | [In Progress](https://github.com/dotnet/roslyn/issues/52221) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) |
| [File-scoped namespace](https://github.com/dotnet/csharplang/issues/137) | [FileScopedNamespaces](https://github.com/dotnet/roslyn/tree/features/FileScopedNamespaces) | [In Progress](https://github.com/dotnet/roslyn/issues/49000) | [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv), [chsienki](https://github.com/chsienki) | [CyrusNajmabadi](https://github.com/CyrusNajmabadi) |
| [Interpolated string improvements](https://github.com/dotnet/csharplang/issues/4487) | [interpolated-string](https://github.com/dotnet/roslyn/tree/features/interpolated-string) | [In Progress](https://github.com/dotnet/roslyn/issues/51499) | [333fred](https://github.com/333fred) | [AlekseyTs](https://github.com/AlekseyTs), [chsienki](https://github.com/chsienki) | [jaredpar](https://github.com/jaredpar) |
| [Parameterless struct constructors](https://github.com/dotnet/csharplang/issues/99) | [struct-ctors](https://github.com/dotnet/roslyn/tree/features/struct-ctors) | [In Progress](https://github.com/dotnet/roslyn/issues/51698) | [cston](https://github.com/cston) | [jcouv](https://github.com/jcouv), [333fred](https://github.com/333fred) | [jcouv](https://github.com/jouv) |
| [Lambda improvements](https://github.com/dotnet/csharplang/blob/main/proposals/lambda-improvements.md) | [lambdas](https://github.com/dotnet/roslyn/tree/features/lambdas) | [In Progress](https://github.com/dotnet/roslyn/issues/52192) | [cston](https://github.com/cston) | [333fred](https://github.com/333fred), [jcouv](https://github.com/jcouv) | [jaredpar](https://github.com/jaredpar) |
| [nameof(parameter)](https://github.com/dotnet/csharplang/issues/373) | main | [In Progress](https://github.com/dotnet/roslyn/issues/40524) | [jcouv](https://github.com/jcouv) | TBD | [jcouv](https://github.com/jcouv) |
-| [Improved Definite Assignment](https://github.com/dotnet/csharplang/issues/4465) | [improved-definite-assignment](https://github.com/dotnet/roslyn/tree/features/improved-definite-assignment) | [Merged into 17.0](https://github.com/dotnet/roslyn/issues/51463) | [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) | [jaredpar](https://github.com/jaredpar) |
| [Relax ordering of `ref` and `partial` modifiers](https://github.com/dotnet/csharplang/issues/946) | [ref-partial](https://github.com/dotnet/roslyn/tree/features/ref-partial) | In Progress | [alrz](https://github.com/alrz) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
| [Parameter null-checking](https://github.com/dotnet/csharplang/issues/2145) | [param-nullchecking](https://github.com/dotnet/roslyn/tree/features/param-nullchecking) | [In Progress](https://github.com/dotnet/roslyn/issues/36024) | [fayrose](https://github.com/fayrose) | [agocke](https://github.com/agocke) | [jaredpar](https://github.com/jaredpar) |
| [Caller expression attribute](https://github.com/dotnet/csharplang/issues/287) | [caller-argument-expression](https://github.com/dotnet/roslyn/tree/features/caller-argument-expression) | [In Progress](https://github.com/dotnet/roslyn/issues/52745) | [Youssef1313](https://github.com/Youssef1313) | [333fred](https://github.com/333fred),[AlekseyTs](https://github.com/AlekseyTs) | [jcouv](https://github.com/jcouv) |
| [Generic attributes](https://github.com/dotnet/csharplang/issues/124) | [generic-attributes](https://github.com/dotnet/roslyn/tree/features/generic-attributes) | [In Progress](https://github.com/dotnet/roslyn/issues/36285) | [AviAvni](https://github.com/AviAvni) | [agocke](https://github.com/agocke) | [mattwar](https://github.com/mattwar) |
| [Default in deconstruction](https://github.com/dotnet/roslyn/pull/25562) | [decon-default](https://github.com/dotnet/roslyn/tree/features/decon-default) | [Implemented](https://github.com/dotnet/roslyn/issues/25559) | [jcouv](https://github.com/jcouv) | [gafter](https://github.com/gafter) | [jcouv](https://github.com/jcouv) |
-| [Constant Interpolated Strings](https://github.com/dotnet/csharplang/issues/2951) | main | [Merged into 16.9p3](https://github.com/dotnet/roslyn/pull/49676) | [kevinsun-dev](https://github.com/kevinsun-dev) | [333fred](https://github.com/333fred) | [jaredar](https://github.com/jaredpar), [agocke](https://github.com/agocke) |
-| [Mix declarations and variables in deconstruction](https://github.com/dotnet/csharplang/issues/125) | main | [Merged into 16.10](https://github.com/dotnet/roslyn/issues/47746) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [jcouv](https://github.com/jcouv) | [MadsTorgersen](https://github.com/MadsTorgersen) |
| [List patterns](https://github.com/dotnet/csharplang/issues/3435) | [list-patterns](https://github.com/dotnet/roslyn/tree/features/list-patterns) | [In Progress](https://github.com/dotnet/roslyn/issues/51289) | [alrz](https://github.com/alrz) | [jcouv](https://github.com/jcouv), [333fred](https://github.com/333fred) | [333fred](https://github.com/333fred) |
+
+
+# C# 10.0
+
+| Feature | Branch | State | Developer | Reviewer | LDM Champ |
+| ------- | ------ | ----- | --------- | -------- | --------- |
+| [Record structs](https://github.com/dotnet/csharplang/issues/4334) | [record-structs](https://github.com/dotnet/roslyn/tree/features/record-structs) | [Merged into 16.11](https://github.com/dotnet/roslyn/issues/51199) | [jcouv](https://github.com/jcouv) | [AlekseyTs](https://github.com/AlekseyTs), [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) |
+| [Global Using Directive](https://github.com/dotnet/csharplang/issues/3428) | [GlobalUsingDirective](https://github.com/dotnet/roslyn/tree/features/GlobalUsingDirective) | [Merged into 16.11](https://github.com/dotnet/roslyn/issues/51307) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [cston](https://github.com/cston) | [AlekseyTs](https://github.com/AlekseyTs) |
+| [Improved Definite Assignment](https://github.com/dotnet/csharplang/issues/4465) | [improved-definite-assignment](https://github.com/dotnet/roslyn/tree/features/improved-definite-assignment) | [Merged into 17.0](https://github.com/dotnet/roslyn/issues/51463) | [RikkiGibson](https://github.com/RikkiGibson) | [jcouv](https://github.com/jcouv) | [jaredpar](https://github.com/jaredpar) |
+| [Constant Interpolated Strings](https://github.com/dotnet/csharplang/issues/2951) | main | [Merged into 16.9p3](https://github.com/dotnet/roslyn/pull/49676) | [kevinsun-dev](https://github.com/kevinsun-dev) | [333fred](https://github.com/333fred) | [jaredar](https://github.com/jaredpar), [agocke](https://github.com/agocke) |
| [Extended property patterns](https://github.com/dotnet/csharplang/issues/4394) | [extended-property-patterns](https://github.com/dotnet/roslyn/tree/features/extended-property-patterns) | [Merged into 17.0](https://github.com/dotnet/roslyn/issues/52468) | [alrz](https://github.com/alrz) | [jcouv](https://github.com/jcouv), [333fred](https://github.com/333fred) | [333fred](https://github.com/333fred) |
| [Sealed record ToString](https://github.com/dotnet/csharplang/issues/4174) | main | [Merged](https://github.com/dotnet/roslyn/issues/52031) | [thomaslevesque](https://github.com/thomaslevesque/) | [jcouv](https://github.com/jcouv) | [333fred](https://github.com/333fred) |
-| [Source Generator V2 APIs](https://github.com/dotnet/roslyn/issues/51257) | [features/source-generators](https://github.com/dotnet/roslyn/tree/features/source-generators) | [In Progress](https://github.com/dotnet/roslyn/issues/51257) | [chsienki](https://github.com/chsienki/) | [rikkigibson](https://github.com/rikkigibson), [jaredpar](https://github.com/jaredpar), [cston](https://github.com/cston) | N/A |
-| [Async method builder override](https://github.com/dotnet/csharplang/issues/1407) | main | [In Progress](https://github.com/dotnet/roslyn/issues/51999) | [jcouv](https://github.com/jcouv) | TBD | [stephentoub](https://github.com/stephentoub) |
+| [Source Generator V2 APIs](https://github.com/dotnet/roslyn/issues/51257) | [features/source-generators](https://github.com/dotnet/roslyn/tree/features/source-generators) | [Merged into 17.0p2](https://github.com/dotnet/roslyn/issues/51257) | [chsienki](https://github.com/chsienki/) | [rikkigibson](https://github.com/rikkigibson), [jaredpar](https://github.com/jaredpar), [cston](https://github.com/cston) | N/A |
+| [Mix declarations and variables in deconstruction](https://github.com/dotnet/csharplang/issues/125) | main | [Merged into 16.10](https://github.com/dotnet/roslyn/issues/47746) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [jcouv](https://github.com/jcouv) | [MadsTorgersen](https://github.com/MadsTorgersen) |
+| [Async method builder override](https://github.com/dotnet/csharplang/issues/1407) | main | [Merged into 17.0p2](https://github.com/dotnet/roslyn/issues/51999) | [jcouv](https://github.com/jcouv) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [stephentoub](https://github.com/stephentoub) |
+| [Enhanced `#line` directive](https://github.com/dotnet/csharplang/issues/4747) | main | [Merged into 17.0p2](https://github.com/dotnet/roslyn/issues/54509) | [cston](https://github.com/cston) | [jcouv](https://github.com/jcouv), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) |
# VB 16.9
diff --git a/docs/features/StaticAbstractMembersInInterfaces.md b/docs/features/StaticAbstractMembersInInterfaces.md
new file mode 100644
index 0000000000000..ed49e08974677
--- /dev/null
+++ b/docs/features/StaticAbstractMembersInInterfaces.md
@@ -0,0 +1,14 @@
+Static Abstract Members In Interfaces
+=====================================
+
+An interface is allowed to specify abstract static members that implementing classes and structs are then
+required to provide an explicit or implicit implementation of. The members can be accessed off of type
+parameters that are constrained by the interface.
+
+Proposal:
+- https://github.com/dotnet/csharplang/issues/4436
+- https://github.com/dotnet/csharplang/blob/main/proposals/static-abstracts-in-interfaces.md
+
+Feature branch: https://github.com/dotnet/roslyn/tree/features/StaticAbstractMembersInInterfaces
+
+Test plan: https://github.com/dotnet/roslyn/issues/52221
\ No newline at end of file
diff --git a/docs/features/refout.md b/docs/features/refout.md
index 0571529797481..4487d9f006353 100644
--- a/docs/features/refout.md
+++ b/docs/features/refout.md
@@ -61,13 +61,13 @@ An additional task, called `CopyRefAssembly`, is provided along with the existin
As a side-note, `CopyRefAssembly` uses the same assembly resolution/redirection trick as `Csc` and `Vbc`, to avoid type loading problems with `System.IO.FileSystem`.
### CodeAnalysis APIs
-Prior to C# 7.1, it was already possible to produce metadata-only assemblies by using `EmitOptions.EmitMetadataOnly`, which is used in IDE scenarios with cross-language dependencies.
+Prior to C# 7.1, it was already possible to produce metadata-only assemblies by using `EmitOptions.EmitMetadataOnly`, which is used in IDE scenarios with cross-language dependencies.
-With C# 7.1, the compiler now honours the `EmitOptions.IncludePrivateMembers` flag as well. When combined with `EmitMetadataOnly` or a `metadataPeStream` in `Emit`, a ref assembly is produced.
+With C# 7.1, the compiler now honours the `EmitOptions.IncludePrivateMembers` flag as well. When combined with `EmitMetadataOnly` or a `metadataPeStream` in `Emit`, a ref assembly is produced.
-The diagnostic check for emitting methods lacking a body (`void M();`) is filtered from declaration diagnostics, so such code will successfully emit with `EmitMetadataOnly`.
+Method bodies aren't compiled when using `EmitMetadataOnly`. Even the diagnostic check for emitting methods lacking a body (`void M();`) is filtered from declaration diagnostics, so such code will successfully emit with `EmitMetadataOnly`.
-Later on, the `EmitOptions.TolerateErrors` flag will allow emitting error types as well.
+Later on, the `EmitOptions.TolerateErrors` flag will allow emitting error types as well.
`Emit` was modified to produce a new PE section called ".mvid" containing a copy of the MVID, when emitting ref assemblies. This makes it easy for `CopyRefAssembly` to extract and compare MVIDs from ref assemblies.
Going back to the 4 driving scenarios:
diff --git a/dotnet-tools.json b/dotnet-tools.json
index 10d642464725d..6ab0998319770 100644
--- a/dotnet-tools.json
+++ b/dotnet-tools.json
@@ -2,7 +2,7 @@
"isRoot": true,
"tools": {
"dotnet-format": {
- "version": "5.0.141503",
+ "version": "6.0.231801",
"commands": [
"dotnet-format"
]
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 1550d473a9f8a..629edf6934c73 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -6,9 +6,9 @@
7e80445ee82adbf9a8e6ae601ac5e239d982afaa
-
+
https://github.com/dotnet/source-build
- c06ae1212bd69e9fe52bed0b0a7d79cc8ea39054
+ bf8af9a5202d5016b4bcf3424fac6bac55ef7c8e
@@ -18,9 +18,9 @@
78da7776965b428ff31da8f1ff2cb073506212b7
-
+
https://github.com/dotnet/roslyn
- 5b972bceb846f5d15f991a479e285067a75103e4
+ 03a07d1dd606ce11d62c9a595041c4c2d44c39e3
https://github.com/dotnet/arcade
diff --git a/eng/Versions.props b/eng/Versions.props
index 5b00a7d5603e9..c2b3f72ab58ce 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -8,7 +8,7 @@
4
0
0
- 2
+ 3
$(MajorVersion).$(MinorVersion).$(PatchVersion)
3.3.3-beta1.21105.3
6.0.0-preview1.21054.10
- 1.0.1-beta1.20623.3
- 3.9.0
+ 1.1.0-beta1.21322.2
+ 3.10.0
16.10.230
5.0.0-alpha1.19409.1
5.0.0-preview.1.20112.8
- 16.10.1202
+ 16.11.2
16.10.31320.204
16.5.0
+
@@ -404,6 +407,7 @@
+
+ <_MaxSupportedLangVersion Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' AND '$(_TargetFrameworkVersionWithoutV)' == '6.0' AND
+ '$(_MaxSupportedLangVersion)' == ''">10.0
+
$(_MaxSupportedLangVersion)
$(_MaxSupportedLangVersion)
diff --git a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets
index 5c035bb1ba9ff..d742060eeeab5 100644
--- a/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets
+++ b/src/Compilers/Core/MSBuildTask/Microsoft.Managed.Core.targets
@@ -50,10 +50,19 @@
+
+
+
-
+
<_SkipAnalyzers>
+ <_ImplicitlySkipAnalyzers>
+
+ <_ImplicitlySkipAnalyzers>true
+ <_SkipAnalyzers>true
+
+
+
+
+
+
+
+ <_LastBuildWithSkipAnalyzers>$(IntermediateOutputPath)$(MSBuildProjectFile).BuildWithSkipAnalyzers
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Compilers/VisualBasic/Portable/Generated/BoundNodes.xml.Generated.vb b/src/Compilers/VisualBasic/Portable/Generated/BoundNodes.xml.Generated.vb
index 08fbbf38055a0..9dd3584870b2a 100644
--- a/src/Compilers/VisualBasic/Portable/Generated/BoundNodes.xml.Generated.vb
+++ b/src/Compilers/VisualBasic/Portable/Generated/BoundNodes.xml.Generated.vb
@@ -3758,14 +3758,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class BoundObjectInitializerExpression
Inherits BoundObjectInitializerExpressionBase
- Public Sub New(syntax As SyntaxNode, createTemporaryLocalForInitialization As Boolean, binder As Binder, placeholderOpt As BoundWithLValueExpressionPlaceholder, initializers As ImmutableArray(Of BoundExpression), type As TypeSymbol, Optional hasErrors As Boolean = False)
+ Public Sub New(syntax As SyntaxNode, createTemporaryLocalForInitialization As Boolean, placeholderOpt As BoundWithLValueExpressionPlaceholder, initializers As ImmutableArray(Of BoundExpression), type As TypeSymbol, Optional hasErrors As Boolean = False)
MyBase.New(BoundKind.ObjectInitializerExpression, syntax, placeholderOpt, initializers, type, hasErrors OrElse placeholderOpt.NonNullAndHasErrors() OrElse initializers.NonNullAndHasErrors())
- Debug.Assert(binder IsNot Nothing, "Field 'binder' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Debug.Assert(Not (initializers.IsDefault), "Field 'initializers' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Me._CreateTemporaryLocalForInitialization = createTemporaryLocalForInitialization
- Me._Binder = binder
Validate()
End Sub
@@ -3781,21 +3779,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
- Private ReadOnly _Binder As Binder
- Public ReadOnly Property Binder As Binder
- Get
- Return _Binder
- End Get
- End Property
-
Public Overrides Function Accept(visitor as BoundTreeVisitor) As BoundNode
Return visitor.VisitObjectInitializerExpression(Me)
End Function
- Public Function Update(createTemporaryLocalForInitialization As Boolean, binder As Binder, placeholderOpt As BoundWithLValueExpressionPlaceholder, initializers As ImmutableArray(Of BoundExpression), type As TypeSymbol) As BoundObjectInitializerExpression
- If createTemporaryLocalForInitialization <> Me.CreateTemporaryLocalForInitialization OrElse binder IsNot Me.Binder OrElse placeholderOpt IsNot Me.PlaceholderOpt OrElse initializers <> Me.Initializers OrElse type IsNot Me.Type Then
- Dim result = New BoundObjectInitializerExpression(Me.Syntax, createTemporaryLocalForInitialization, binder, placeholderOpt, initializers, type, Me.HasErrors)
+ Public Function Update(createTemporaryLocalForInitialization As Boolean, placeholderOpt As BoundWithLValueExpressionPlaceholder, initializers As ImmutableArray(Of BoundExpression), type As TypeSymbol) As BoundObjectInitializerExpression
+ If createTemporaryLocalForInitialization <> Me.CreateTemporaryLocalForInitialization OrElse placeholderOpt IsNot Me.PlaceholderOpt OrElse initializers <> Me.Initializers OrElse type IsNot Me.Type Then
+ Dim result = New BoundObjectInitializerExpression(Me.Syntax, createTemporaryLocalForInitialization, placeholderOpt, initializers, type, Me.HasErrors)
result.CopyAttributes(Me)
Return result
End If
@@ -4500,14 +4491,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class BoundAsNewLocalDeclarations
Inherits BoundLocalDeclarationBase
- Public Sub New(syntax As SyntaxNode, localDeclarations As ImmutableArray(Of BoundLocalDeclaration), initializer As BoundExpression, Optional hasErrors As Boolean = False)
+ Public Sub New(syntax As SyntaxNode, localDeclarations As ImmutableArray(Of BoundLocalDeclaration), initializer As BoundExpression, binder As Binder, Optional hasErrors As Boolean = False)
MyBase.New(BoundKind.AsNewLocalDeclarations, syntax, hasErrors OrElse localDeclarations.NonNullAndHasErrors() OrElse initializer.NonNullAndHasErrors())
Debug.Assert(Not (localDeclarations.IsDefault), "Field 'localDeclarations' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Debug.Assert(initializer IsNot Nothing, "Field 'initializer' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
+ Debug.Assert(binder IsNot Nothing, "Field 'binder' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Me._LocalDeclarations = localDeclarations
Me._Initializer = initializer
+ Me._Binder = binder
End Sub
@@ -4525,14 +4518,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Get
End Property
+ Private ReadOnly _Binder As Binder
+ Public ReadOnly Property Binder As Binder
+ Get
+ Return _Binder
+ End Get
+ End Property
+
Public Overrides Function Accept(visitor as BoundTreeVisitor) As BoundNode
Return visitor.VisitAsNewLocalDeclarations(Me)
End Function
- Public Function Update(localDeclarations As ImmutableArray(Of BoundLocalDeclaration), initializer As BoundExpression) As BoundAsNewLocalDeclarations
- If localDeclarations <> Me.LocalDeclarations OrElse initializer IsNot Me.Initializer Then
- Dim result = New BoundAsNewLocalDeclarations(Me.Syntax, localDeclarations, initializer, Me.HasErrors)
+ Public Function Update(localDeclarations As ImmutableArray(Of BoundLocalDeclaration), initializer As BoundExpression, binder As Binder) As BoundAsNewLocalDeclarations
+ If localDeclarations <> Me.LocalDeclarations OrElse initializer IsNot Me.Initializer OrElse binder IsNot Me.Binder Then
+ Dim result = New BoundAsNewLocalDeclarations(Me.Syntax, localDeclarations, initializer, binder, Me.HasErrors)
result.CopyAttributes(Me)
Return result
End If
@@ -4611,13 +4611,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend MustInherit Class BoundFieldOrPropertyInitializer
Inherits BoundInitializer
- Protected Sub New(kind As BoundKind, syntax as SyntaxNode, memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, Optional hasErrors As Boolean = False)
+ Protected Sub New(kind As BoundKind, syntax as SyntaxNode, memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, binderOpt As Binder, Optional hasErrors As Boolean = False)
MyBase.New(kind, syntax, hasErrors)
Debug.Assert(initialValue IsNot Nothing, "Field 'initialValue' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Me._MemberAccessExpressionOpt = memberAccessExpressionOpt
Me._InitialValue = initialValue
+ Me._BinderOpt = binderOpt
End Sub
@@ -4634,13 +4635,20 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return _InitialValue
End Get
End Property
+
+ Private ReadOnly _BinderOpt As Binder
+ Public ReadOnly Property BinderOpt As Binder
+ Get
+ Return _BinderOpt
+ End Get
+ End Property
End Class
Partial Friend NotInheritable Class BoundFieldInitializer
Inherits BoundFieldOrPropertyInitializer
- Public Sub New(syntax As SyntaxNode, initializedFields As ImmutableArray(Of FieldSymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, Optional hasErrors As Boolean = False)
- MyBase.New(BoundKind.FieldInitializer, syntax, memberAccessExpressionOpt, initialValue, hasErrors OrElse memberAccessExpressionOpt.NonNullAndHasErrors() OrElse initialValue.NonNullAndHasErrors())
+ Public Sub New(syntax As SyntaxNode, initializedFields As ImmutableArray(Of FieldSymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, binderOpt As Binder, Optional hasErrors As Boolean = False)
+ MyBase.New(BoundKind.FieldInitializer, syntax, memberAccessExpressionOpt, initialValue, binderOpt, hasErrors OrElse memberAccessExpressionOpt.NonNullAndHasErrors() OrElse initialValue.NonNullAndHasErrors())
Debug.Assert(Not (initializedFields.IsDefault), "Field 'initializedFields' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Debug.Assert(initialValue IsNot Nothing, "Field 'initialValue' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
@@ -4661,9 +4669,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return visitor.VisitFieldInitializer(Me)
End Function
- Public Function Update(initializedFields As ImmutableArray(Of FieldSymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression) As BoundFieldInitializer
- If initializedFields <> Me.InitializedFields OrElse memberAccessExpressionOpt IsNot Me.MemberAccessExpressionOpt OrElse initialValue IsNot Me.InitialValue Then
- Dim result = New BoundFieldInitializer(Me.Syntax, initializedFields, memberAccessExpressionOpt, initialValue, Me.HasErrors)
+ Public Function Update(initializedFields As ImmutableArray(Of FieldSymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, binderOpt As Binder) As BoundFieldInitializer
+ If initializedFields <> Me.InitializedFields OrElse memberAccessExpressionOpt IsNot Me.MemberAccessExpressionOpt OrElse initialValue IsNot Me.InitialValue OrElse binderOpt IsNot Me.BinderOpt Then
+ Dim result = New BoundFieldInitializer(Me.Syntax, initializedFields, memberAccessExpressionOpt, initialValue, binderOpt, Me.HasErrors)
result.CopyAttributes(Me)
Return result
End If
@@ -4674,8 +4682,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend NotInheritable Class BoundPropertyInitializer
Inherits BoundFieldOrPropertyInitializer
- Public Sub New(syntax As SyntaxNode, initializedProperties As ImmutableArray(Of PropertySymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, Optional hasErrors As Boolean = False)
- MyBase.New(BoundKind.PropertyInitializer, syntax, memberAccessExpressionOpt, initialValue, hasErrors OrElse memberAccessExpressionOpt.NonNullAndHasErrors() OrElse initialValue.NonNullAndHasErrors())
+ Public Sub New(syntax As SyntaxNode, initializedProperties As ImmutableArray(Of PropertySymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, binderOpt As Binder, Optional hasErrors As Boolean = False)
+ MyBase.New(BoundKind.PropertyInitializer, syntax, memberAccessExpressionOpt, initialValue, binderOpt, hasErrors OrElse memberAccessExpressionOpt.NonNullAndHasErrors() OrElse initialValue.NonNullAndHasErrors())
Debug.Assert(Not (initializedProperties.IsDefault), "Field 'initializedProperties' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
Debug.Assert(initialValue IsNot Nothing, "Field 'initialValue' cannot be null (use Null=""allow"" in BoundNodes.xml to remove this check)")
@@ -4696,9 +4704,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return visitor.VisitPropertyInitializer(Me)
End Function
- Public Function Update(initializedProperties As ImmutableArray(Of PropertySymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression) As BoundPropertyInitializer
- If initializedProperties <> Me.InitializedProperties OrElse memberAccessExpressionOpt IsNot Me.MemberAccessExpressionOpt OrElse initialValue IsNot Me.InitialValue Then
- Dim result = New BoundPropertyInitializer(Me.Syntax, initializedProperties, memberAccessExpressionOpt, initialValue, Me.HasErrors)
+ Public Function Update(initializedProperties As ImmutableArray(Of PropertySymbol), memberAccessExpressionOpt As BoundExpression, initialValue As BoundExpression, binderOpt As Binder) As BoundPropertyInitializer
+ If initializedProperties <> Me.InitializedProperties OrElse memberAccessExpressionOpt IsNot Me.MemberAccessExpressionOpt OrElse initialValue IsNot Me.InitialValue OrElse binderOpt IsNot Me.BinderOpt Then
+ Dim result = New BoundPropertyInitializer(Me.Syntax, initializedProperties, memberAccessExpressionOpt, initialValue, binderOpt, Me.HasErrors)
result.CopyAttributes(Me)
Return result
End If
@@ -12421,7 +12429,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim placeholderOpt As BoundWithLValueExpressionPlaceholder = DirectCast(Me.Visit(node.PlaceholderOpt), BoundWithLValueExpressionPlaceholder)
Dim initializers As ImmutableArray(Of BoundExpression) = Me.VisitList(node.Initializers)
Dim type as TypeSymbol = Me.VisitType(node.Type)
- Return node.Update(node.CreateTemporaryLocalForInitialization, node.Binder, placeholderOpt, initializers, type)
+ Return node.Update(node.CreateTemporaryLocalForInitialization, placeholderOpt, initializers, type)
End Function
Public Overrides Function VisitCollectionInitializerExpression(node As BoundCollectionInitializerExpression) As BoundNode
@@ -12506,7 +12514,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitAsNewLocalDeclarations(node As BoundAsNewLocalDeclarations) As BoundNode
Dim localDeclarations As ImmutableArray(Of BoundLocalDeclaration) = Me.VisitList(node.LocalDeclarations)
Dim initializer As BoundExpression = DirectCast(Me.Visit(node.Initializer), BoundExpression)
- Return node.Update(localDeclarations, initializer)
+ Return node.Update(localDeclarations, initializer, node.Binder)
End Function
Public Overrides Function VisitDimStatement(node As BoundDimStatement) As BoundNode
@@ -12522,13 +12530,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitFieldInitializer(node As BoundFieldInitializer) As BoundNode
Dim memberAccessExpressionOpt As BoundExpression = DirectCast(Me.Visit(node.MemberAccessExpressionOpt), BoundExpression)
Dim initialValue As BoundExpression = DirectCast(Me.Visit(node.InitialValue), BoundExpression)
- Return node.Update(node.InitializedFields, memberAccessExpressionOpt, initialValue)
+ Return node.Update(node.InitializedFields, memberAccessExpressionOpt, initialValue, node.BinderOpt)
End Function
Public Overrides Function VisitPropertyInitializer(node As BoundPropertyInitializer) As BoundNode
Dim memberAccessExpressionOpt As BoundExpression = DirectCast(Me.Visit(node.MemberAccessExpressionOpt), BoundExpression)
Dim initialValue As BoundExpression = DirectCast(Me.Visit(node.InitialValue), BoundExpression)
- Return node.Update(node.InitializedProperties, memberAccessExpressionOpt, initialValue)
+ Return node.Update(node.InitializedProperties, memberAccessExpressionOpt, initialValue, node.BinderOpt)
End Function
Public Overrides Function VisitParameterEqualsValue(node As BoundParameterEqualsValue) As BoundNode
@@ -13663,7 +13671,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitObjectInitializerExpression(node As BoundObjectInitializerExpression, arg As Object) As TreeDumperNode
Return New TreeDumperNode("objectInitializerExpression", Nothing, New TreeDumperNode() {
New TreeDumperNode("createTemporaryLocalForInitialization", node.CreateTemporaryLocalForInitialization, Nothing),
- New TreeDumperNode("binder", node.Binder, Nothing),
New TreeDumperNode("placeholderOpt", Nothing, new TreeDumperNode() {Visit(node.PlaceholderOpt, Nothing)}),
New TreeDumperNode("initializers", Nothing, From x In node.Initializers Select Visit(x, Nothing)),
New TreeDumperNode("type", node.Type, Nothing)
@@ -13786,7 +13793,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitAsNewLocalDeclarations(node As BoundAsNewLocalDeclarations, arg As Object) As TreeDumperNode
Return New TreeDumperNode("asNewLocalDeclarations", Nothing, New TreeDumperNode() {
New TreeDumperNode("localDeclarations", Nothing, From x In node.LocalDeclarations Select Visit(x, Nothing)),
- New TreeDumperNode("initializer", Nothing, new TreeDumperNode() {Visit(node.Initializer, Nothing)})
+ New TreeDumperNode("initializer", Nothing, new TreeDumperNode() {Visit(node.Initializer, Nothing)}),
+ New TreeDumperNode("binder", node.Binder, Nothing)
})
End Function
@@ -13805,7 +13813,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return New TreeDumperNode("fieldInitializer", Nothing, New TreeDumperNode() {
New TreeDumperNode("initializedFields", node.InitializedFields, Nothing),
New TreeDumperNode("memberAccessExpressionOpt", Nothing, new TreeDumperNode() {Visit(node.MemberAccessExpressionOpt, Nothing)}),
- New TreeDumperNode("initialValue", Nothing, new TreeDumperNode() {Visit(node.InitialValue, Nothing)})
+ New TreeDumperNode("initialValue", Nothing, new TreeDumperNode() {Visit(node.InitialValue, Nothing)}),
+ New TreeDumperNode("binderOpt", node.BinderOpt, Nothing)
})
End Function
@@ -13813,7 +13822,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return New TreeDumperNode("propertyInitializer", Nothing, New TreeDumperNode() {
New TreeDumperNode("initializedProperties", node.InitializedProperties, Nothing),
New TreeDumperNode("memberAccessExpressionOpt", Nothing, new TreeDumperNode() {Visit(node.MemberAccessExpressionOpt, Nothing)}),
- New TreeDumperNode("initialValue", Nothing, new TreeDumperNode() {Visit(node.InitialValue, Nothing)})
+ New TreeDumperNode("initialValue", Nothing, new TreeDumperNode() {Visit(node.InitialValue, Nothing)}),
+ New TreeDumperNode("binderOpt", node.BinderOpt, Nothing)
})
End Function
diff --git a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_AsNewLocalDeclarations.vb b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_AsNewLocalDeclarations.vb
index 7d0feb839fcdf..b4b23ed1b155f 100644
--- a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_AsNewLocalDeclarations.vb
+++ b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_AsNewLocalDeclarations.vb
@@ -16,27 +16,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitAsNewLocalDeclarations(node As BoundAsNewLocalDeclarations) As BoundNode
Dim builder = ArrayBuilder(Of BoundStatement).GetInstance()
- ' The initializer expression may contain placeholder values and typically they are replaced with bound locals that
- ' get created in the local rewriter when rewriting the expression.
- '
- ' There is one case where the placeholder does not get replaced by a bound temporary and needs to be replaced by
- ' the currently declared local. This is the case for an object creation expression with a object initializer if it's
- ' used in an AsNew declaration and the type is a value type, e.g.:
- ' Dim x As New ValType() With {...}
- ' or
- ' Dim x, y As New ValType() With {...}
- ' Because only this method knows the bound local that the placeholder will be replaced with, we need to fill
- ' the replacement map here, before rewriting the local declaration (there is a special case, because the first
- ' example will be bound to a BoundLocalDeclaration, see LocalRewriter.VisitLocalDeclaration for the special case).
- '
- Dim objectInitializer As BoundObjectInitializerExpression = GetBoundObjectInitializerFromInitializer(node.Initializer)
-
Dim localDeclarations = node.LocalDeclarations
For declarationIndex = 0 To localDeclarations.Length - 1
Dim localDeclaration = localDeclarations(declarationIndex)
Debug.Assert(localDeclaration.InitializerOpt Is Nothing)
- Dim rewrittenInitializer As BoundNode = Nothing
+ Dim rewrittenInitializer As BoundNode
Dim localSymbol = localDeclaration.LocalSymbol
Dim staticLocalBackingFields As KeyValuePair(Of SynthesizedStaticLocalBackingField, SynthesizedStaticLocalBackingField) = Nothing
@@ -45,52 +30,61 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
staticLocalBackingFields = CreateBackingFieldsForStaticLocal(localSymbol, hasInitializer:=True)
End If
+ Dim initializerToRewrite As BoundExpression
+
+ If declarationIndex = 0 Then
+ initializerToRewrite = node.Initializer
+ Else
+ ' For all variables except the first one we rebind the initializer
+ ' and throw away diagnostics, those are supposed to be reported in the first
+ ' binding and don't need to be duplicated as Dev10/11 does
+ '
+ ' Note that we have to rebind the initializers because current implementation of lambda
+ ' rewriter does not handle correctly blocks and locals which are reused in bound tree.
+ ' Actually it seems to heavily rely on an assumption that the bound tree is a tree, not
+ ' a DAG, with just minor deviations. Thus, the natural way of just rewriting bound
+ ' initializer stored in node.Initializer simply does not work because rewriting *may*
+ ' keep many blocks and locals unchanged and reuse them in all rewritten initializers,
+ ' in which case if we have a lambda inside the initializer lambda rewriter simply throws.
+ '
+ ' Another option to satisfy lambda rewriter would be to deep-clone bound tree, but
+ ' in this case we will also have to clone all locals and all references to locals.
+ ' We might want to look into this option later.
+
+ Debug.Assert(node.Syntax IsNot Nothing)
+ Debug.Assert(node.Syntax.Kind = SyntaxKind.VariableDeclarator)
+
+ Dim varDecl = DirectCast(node.Syntax, VariableDeclaratorSyntax)
+ Dim asNew = DirectCast(varDecl.AsClause, AsNewClauseSyntax)
+
+ ' Rebind and discard diagnostics
+ initializerToRewrite = node.Binder.BindVariableDeclaration(varDecl, varDecl.Names(declarationIndex), asNew, Nothing, BindingDiagnosticBag.Discarded, skipAsNewInitializer:=False).InitializerOpt
+ End If
+
+ ' The initializer expression may contain placeholder values and typically they are replaced with bound locals that
+ ' get created in the local rewriter when rewriting the expression.
+ '
+ ' There is one case where the placeholder does not get replaced by a bound temporary and needs to be replaced by
+ ' the currently declared local. This is the case for an object creation expression with a object initializer if it's
+ ' used in an AsNew declaration and the type is a value type, e.g.:
+ ' Dim x As New ValType() With {...}
+ ' or
+ ' Dim x, y As New ValType() With {...}
+ ' Because only this method knows the bound local that the placeholder will be replaced with, we need to fill
+ ' the replacement map here, before rewriting the local declaration (there is a special case, because the first
+ ' example will be bound to a BoundLocalDeclaration, see LocalRewriter.VisitLocalDeclaration for the special case).
+ '
+ Dim objectInitializer As BoundObjectInitializerExpression = GetBoundObjectInitializerFromInitializer(initializerToRewrite)
+
+
' rewrite the initializer for each declared variable because the initializer may contain placeholders that need
' to be replaced with the current bound local
+
If objectInitializer IsNot Nothing Then
Debug.Assert(objectInitializer.PlaceholderOpt IsNot Nothing)
- Dim initializerToRewrite As BoundExpression = node.Initializer
Dim placeholder As BoundWithLValueExpressionPlaceholder = objectInitializer.PlaceholderOpt
- If declarationIndex > 0 Then
-
- ' For all variables except the first one we rebind the initializer
- ' and throw away diagnostics, those are supposed to be reported in the first
- ' binding and don't need to be duplicated as Dev10/11 does
- '
- ' Note that we have to rebind the initializers because current implementation of lambda
- ' rewriter does not handle correctly blocks and locals which are reused in bound tree.
- ' Actually it seems to heavily rely on an assumption that the bound tree is a tree, not
- ' a DAG, with just minor deviations. Thus, the natural way of just rewriting bound
- ' initializer stored in node.Initializer simply does not work because rewriting *may*
- ' keep many blocks and locals unchanged and reuse them in all rewritten initializers,
- ' in which case if we have a lambda inside the initializer lambda rewriter simply throws.
- '
- ' Another option to satisfy lambda rewriter would be to deep-clone bound tree, but
- ' in this case we will also have to clone all locals and all references to locals.
- ' We might want to look into this option later.
-
- Debug.Assert(node.Syntax IsNot Nothing)
- Debug.Assert(node.Syntax.Kind = SyntaxKind.VariableDeclarator)
- Dim asNew = DirectCast(DirectCast(node.Syntax, VariableDeclaratorSyntax).AsClause, AsNewClauseSyntax)
-
- Dim objectCreationExpressionSyntax = DirectCast(asNew.NewExpression, ObjectCreationExpressionSyntax)
- Dim localType As TypeSymbol = localSymbol.Type
-
- ' New placeholder
- placeholder = New BoundWithLValueExpressionPlaceholder(asNew, localType)
- placeholder.SetWasCompilerGenerated()
-
- ' Rebind and discard diagnostics
- initializerToRewrite = objectInitializer.Binder.BindObjectCreationExpression(asNew.Type,
- objectCreationExpressionSyntax.ArgumentList,
- localType,
- objectCreationExpressionSyntax,
- BindingDiagnosticBag.Discarded,
- placeholder)
- End If
-
If Not objectInitializer.CreateTemporaryLocalForInitialization Then
AddPlaceholderReplacement(placeholder,
VisitExpressionNode(New BoundLocal(localDeclaration.Syntax,
@@ -105,7 +99,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Else
- rewrittenInitializer = Me.VisitAndGenerateObjectCloneIfNeeded(node.Initializer)
+ rewrittenInitializer = Me.VisitAndGenerateObjectCloneIfNeeded(initializerToRewrite)
End If
Dim initialization = RewriteLocalDeclarationAsInitializer(
diff --git a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_FieldOrPropertyInitializer.vb b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_FieldOrPropertyInitializer.vb
index 810ac06c4cd48..6ff410c45917a 100644
--- a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_FieldOrPropertyInitializer.vb
+++ b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_FieldOrPropertyInitializer.vb
@@ -54,23 +54,50 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
meReferenceOpt.SetWasCompilerGenerated()
End If
- Dim objectInitializer As BoundObjectInitializerExpression = Nothing
- Dim createTemporary = True
- If node.InitialValue.Kind = BoundKind.ObjectCreationExpression OrElse node.InitialValue.Kind = BoundKind.NewT Then
- Dim objectCreationExpression = DirectCast(node.InitialValue, BoundObjectCreationExpressionBase)
- If objectCreationExpression.InitializerOpt IsNot Nothing AndAlso
- objectCreationExpression.InitializerOpt.Kind = BoundKind.ObjectInitializerExpression Then
- objectInitializer = DirectCast(objectCreationExpression.InitializerOpt, BoundObjectInitializerExpression)
- createTemporary = objectInitializer.CreateTemporaryLocalForInitialization
- End If
- End If
-
Dim instrument As Boolean = Me.Instrument(node)
For symbolIndex = 0 To initializedSymbols.Length - 1
Dim symbol = initializedSymbols(symbolIndex)
Dim accessExpression As BoundExpression
+ Dim initialValueToRewrite As BoundExpression
+
+ If symbolIndex = 0 Then
+ initialValueToRewrite = node.InitialValue
+ Else
+ ' For all variables except the first one we rebind the initializer
+ ' and throw away diagnostics, those are supposed to be reported in the first
+ ' binding and don't need to be duplicated
+ '
+ ' Note that we have to rebind the initializers because current implementation of lambda
+ ' rewriter does not handle correctly blocks and locals which are reused in bound tree.
+ ' Actually it seems to heavily rely on an assumption that the bound tree is a tree, not
+ ' a DAG, with just minor deviations. Thus, the natural way of just rewriting bound
+ ' initializer stored in node.Initializer simply does not work because rewriting *may*
+ ' keep many blocks and locals unchanged and reuse them in all rewritten initializers,
+ ' in which case if we have a lambda inside the initializer lambda rewriter simply throws.
+
+ If symbol.Kind = SymbolKind.Field Then
+ ' Rebind and discard diagnostics
+ initialValueToRewrite = node.BinderOpt.BindFieldInitializerExpression(syntax, DirectCast(symbol, FieldSymbol), BindingDiagnosticBag.Discarded)
+ Else
+ ' Rebind and discard diagnostics
+ initialValueToRewrite = node.BinderOpt.BindPropertyInitializerExpression(syntax, DirectCast(symbol, PropertySymbol), BindingDiagnosticBag.Discarded)
+ End If
+ End If
+
+ Dim objectInitializer As BoundObjectInitializerExpression = Nothing
+ Dim createTemporary = True
+
+ If initialValueToRewrite.Kind = BoundKind.ObjectCreationExpression OrElse initialValueToRewrite.Kind = BoundKind.NewT Then
+ Dim objectCreationExpression = DirectCast(initialValueToRewrite, BoundObjectCreationExpressionBase)
+ If objectCreationExpression.InitializerOpt IsNot Nothing AndAlso
+ objectCreationExpression.InitializerOpt.Kind = BoundKind.ObjectInitializerExpression Then
+ objectInitializer = DirectCast(objectCreationExpression.InitializerOpt, BoundObjectInitializerExpression)
+ createTemporary = objectInitializer.CreateTemporaryLocalForInitialization
+ End If
+ End If
+
' if there are more than one symbol we need to create a field or property access for each of them
If initializedSymbols.Length > 1 Then
If symbol.Kind = SymbolKind.Field Then
@@ -102,14 +129,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' we need to replace the placeholder with it, so add it to the replacement map
AddPlaceholderReplacement(objectInitializer.PlaceholderOpt, accessExpression)
- rewrittenStatement = VisitExpressionNode(node.InitialValue).ToStatement
+ rewrittenStatement = VisitExpressionNode(initialValueToRewrite).ToStatement
RemovePlaceholderReplacement(objectInitializer.PlaceholderOpt)
Else
' in all other cases we want the initial value be assigned to the member (field or property)
rewrittenStatement = VisitExpression(New BoundAssignmentOperator(syntax,
accessExpression,
- node.InitialValue,
+ initialValueToRewrite,
suppressObjectClone:=False)).ToStatement
End If
diff --git a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreation.vb b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreation.vb
index 2997b04509a1a..3dfbba5c3e195 100644
--- a/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreation.vb
+++ b/src/Compilers/VisualBasic/Portable/Lowering/LocalRewriter/LocalRewriter_ObjectCreation.vb
@@ -388,7 +388,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return ReplaceObjectOrCollectionInitializer(
rewrittenObjectCreationExpression,
node.Update(node.CreateTemporaryLocalForInitialization,
- node.Binder,
node.PlaceholderOpt,
newInitializers.AsImmutableOrNull(),
node.Type))
diff --git a/src/Compilers/VisualBasic/Portable/Lowering/MethodToClassRewriter/MethodToClassRewriter.vb b/src/Compilers/VisualBasic/Portable/Lowering/MethodToClassRewriter/MethodToClassRewriter.vb
index 79265b51e293d..d0eb4b39bfa31 100644
--- a/src/Compilers/VisualBasic/Portable/Lowering/MethodToClassRewriter/MethodToClassRewriter.vb
+++ b/src/Compilers/VisualBasic/Portable/Lowering/MethodToClassRewriter/MethodToClassRewriter.vb
@@ -26,13 +26,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' A mapping from every local variable to its replacement local variable. Local variables
''' are replaced when their types change due to being inside of a lambda within a generic method.
'''
- Protected ReadOnly LocalMap As Dictionary(Of LocalSymbol, LocalSymbol) = New Dictionary(Of LocalSymbol, LocalSymbol)()
+ Protected ReadOnly LocalMap As Dictionary(Of LocalSymbol, LocalSymbol) = New Dictionary(Of LocalSymbol, LocalSymbol)(ReferenceEqualityComparer.Instance)
'''
''' A mapping from every parameter to its replacement parameter. Local variables
''' are replaced when their types change due to being inside of a lambda.
'''
- Protected ReadOnly ParameterMap As Dictionary(Of ParameterSymbol, ParameterSymbol) = New Dictionary(Of ParameterSymbol, ParameterSymbol)()
+ Protected ReadOnly ParameterMap As Dictionary(Of ParameterSymbol, ParameterSymbol) = New Dictionary(Of ParameterSymbol, ParameterSymbol)(ReferenceEqualityComparer.Instance)
Protected ReadOnly PlaceholderReplacementMap As New Dictionary(Of BoundValuePlaceholderBase, BoundExpression)
diff --git a/src/Compilers/VisualBasic/Portable/Microsoft.CodeAnalysis.VisualBasic.vbproj b/src/Compilers/VisualBasic/Portable/Microsoft.CodeAnalysis.VisualBasic.vbproj
index 840b7ecd76e75..a4e3694d5dca4 100644
--- a/src/Compilers/VisualBasic/Portable/Microsoft.CodeAnalysis.VisualBasic.vbproj
+++ b/src/Compilers/VisualBasic/Portable/Microsoft.CodeAnalysis.VisualBasic.vbproj
@@ -8,7 +8,7 @@
..\BasicCodeAnalysisRules.ruleset
true
- partial
+ partial
true
diff --git a/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb b/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb
index d8ad0c0932ccf..3c4cd057ef2f8 100644
--- a/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb
+++ b/src/Compilers/VisualBasic/Portable/SourceGeneration/VisualBasicGeneratorDriver.vb
@@ -16,7 +16,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Sub
Friend Sub New(parseOptions As VisualBasicParseOptions, generators As ImmutableArray(Of ISourceGenerator), optionsProvider As AnalyzerConfigOptionsProvider, additionalTexts As ImmutableArray(Of AdditionalText))
- MyBase.New(parseOptions, generators, optionsProvider, additionalTexts)
+ MyBase.New(parseOptions, generators, optionsProvider, additionalTexts, enableIncremental:=False)
End Sub
Friend Overrides ReadOnly Property MessageProvider As CommonMessageProvider
@@ -34,7 +34,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Function
Public Shared Function Create(generators As ImmutableArray(Of ISourceGenerator), Optional additionalTexts As ImmutableArray(Of AdditionalText) = Nothing, Optional parseOptions As VisualBasicParseOptions = Nothing, Optional analyzerConfigOptionsProvider As AnalyzerConfigOptionsProvider = Nothing) As VisualBasicGeneratorDriver
- Return New VisualBasicGeneratorDriver(parseOptions, generators, analyzerConfigOptionsProvider, additionalTexts)
+ Return New VisualBasicGeneratorDriver(parseOptions, generators, If(analyzerConfigOptionsProvider, CompilerAnalyzerConfigOptionsProvider.Empty), additionalTexts.NullToEmpty())
End Function
Friend Overrides Function CreateSourcesCollection() As AdditionalSourcesCollection
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MemberRefMetadataDecoder.vb b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MemberRefMetadataDecoder.vb
index a1dee50b3df56..3e3985ba83fea 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MemberRefMetadataDecoder.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MemberRefMetadataDecoder.vb
@@ -43,35 +43,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
End Function
'''
- ''' This override changes two things:
- ''' 1) Return type arguments instead of type parameters.
- ''' 2) Handle non-PE types.
+ ''' This override can handle non-PE types.
'''
Protected Overrides Function GetGenericTypeParamSymbol(position As Integer) As TypeSymbol
Dim peType As PENamedTypeSymbol = TryCast(Me._containingType, PENamedTypeSymbol)
If peType IsNot Nothing Then
- While peType IsNot Nothing AndAlso (peType.MetadataArity - peType.Arity) > position
- peType = TryCast(peType.ContainingSymbol, PENamedTypeSymbol)
- End While
-
- If peType Is Nothing OrElse peType.MetadataArity <= position Then
- Return New UnsupportedMetadataTypeSymbol(VBResources.PositionOfTypeParameterTooLarge)
- End If
-
- position -= peType.MetadataArity - peType.Arity
- Debug.Assert(position >= 0 AndAlso position < peType.Arity)
-
- Return peType.TypeArgumentsNoUseSiteDiagnostics(position)
+ Return MyBase.GetGenericTypeParamSymbol(position)
End If
Dim namedType As NamedTypeSymbol = TryCast(Me._containingType, NamedTypeSymbol)
If namedType IsNot Nothing Then
Dim cumulativeArity As Integer
- Dim typeArgument As TypeSymbol = Nothing
+ Dim typeParameter As TypeParameterSymbol = Nothing
- GetGenericTypeArgumentSymbol(position, namedType, cumulativeArity, typeArgument)
- If typeArgument IsNot Nothing Then
- Return typeArgument
+ GetGenericTypeParameterSymbol(position, namedType, cumulativeArity, typeParameter)
+ If typeParameter IsNot Nothing Then
+ Return typeParameter
Else
Debug.Assert(cumulativeArity <= position)
Return New UnsupportedMetadataTypeSymbol(VBResources.PositionOfTypeParameterTooLarge)
@@ -81,7 +68,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Return New UnsupportedMetadataTypeSymbol(VBResources.AssociatedTypeDoesNotHaveTypeParameters)
End Function
- Private Shared Sub GetGenericTypeArgumentSymbol(position As Integer, namedType As NamedTypeSymbol, ByRef cumulativeArity As Integer, ByRef typeArgument As TypeSymbol)
+ Private Shared Sub GetGenericTypeParameterSymbol(position As Integer, namedType As NamedTypeSymbol, ByRef cumulativeArity As Integer, ByRef typeArgument As TypeParameterSymbol)
cumulativeArity = namedType.Arity
typeArgument = Nothing
@@ -91,29 +78,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
If containingType IsNot Nothing Then
Dim containingTypeCumulativeArity As Integer
- GetGenericTypeArgumentSymbol(position, containingType, containingTypeCumulativeArity, typeArgument)
+ GetGenericTypeParameterSymbol(position, containingType, containingTypeCumulativeArity, typeArgument)
cumulativeArity += containingTypeCumulativeArity
arityOffset = containingTypeCumulativeArity
End If
If arityOffset <= position AndAlso position < cumulativeArity Then
Debug.Assert(typeArgument Is Nothing)
- typeArgument = namedType.TypeArgumentsNoUseSiteDiagnostics(position - arityOffset)
+ typeArgument = namedType.TypeParameters(position - arityOffset)
End If
End Sub
'''
- ''' Search through the members of a given type symbol to find the method that matches a particular signature.
+ ''' Search through the members of the type symbol to find the method that matches a particular signature.
'''
- ''' Type containing the desired method symbol.
''' A MemberRef handle that can be used to obtain the name and signature of the method
''' True to only return a method.
''' The matching method symbol, or null if the inputs do not correspond to a valid method.
- Friend Function FindMember(targetTypeSymbol As TypeSymbol, memberRef As MemberReferenceHandle, methodsOnly As Boolean) As Symbol
- If targetTypeSymbol Is Nothing Then
- Return Nothing
- End If
-
+ Friend Function FindMember(memberRef As MemberReferenceHandle, methodsOnly As Boolean) As Symbol
Try
Dim memberName As String = [Module].GetMemberRefNameOrThrow(memberRef)
Dim signatureHandle = [Module].GetSignatureOrThrow(memberRef)
@@ -124,7 +106,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Case SignatureCallingConvention.Default, SignatureCallingConvention.VarArgs
Dim typeParamCount As Integer
Dim targetParamInfo As ParamInfo(Of TypeSymbol)() = Me.DecodeSignatureParametersOrThrow(signaturePointer, signatureHeader, typeParamCount)
- Return FindMethodBySignature(targetTypeSymbol, memberName, signatureHeader, typeParamCount, targetParamInfo)
+ Return FindMethodBySignature(_containingType, memberName, signatureHeader, typeParamCount, targetParamInfo)
Case SignatureKind.Field
If methodsOnly Then
@@ -134,7 +116,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Dim customModifiers As ImmutableArray(Of ModifierInfo(Of TypeSymbol)) = Nothing
Dim type As TypeSymbol = Me.DecodeFieldSignature(signaturePointer, customModifiers)
- Return FindFieldBySignature(targetTypeSymbol, memberName, customModifiers, type)
+ Return FindFieldBySignature(_containingType, memberName, customModifiers, type)
Case Else
' error
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb
index 012387b04a03d..b5c1a53d2eada 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/MetadataDecoder.vb
@@ -458,8 +458,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
' We're going to use a special decoder that can generate usable symbols for type parameters without full context.
' (We're not just using a different type - we're also changing the type context.)
- Dim memberRefDecoder = New MemberRefMetadataDecoder(moduleSymbol, targetTypeSymbol)
- Return memberRefDecoder.FindMember(targetTypeSymbol, memberRef, methodsOnly)
+ Dim memberRefDecoder = New MemberRefMetadataDecoder(moduleSymbol, targetTypeSymbol.OriginalDefinition)
+
+ Dim definition = memberRefDecoder.FindMember(memberRef, methodsOnly)
+
+ If definition IsNot Nothing AndAlso Not targetTypeSymbol.IsDefinition Then
+ Return definition.AsMember(DirectCast(targetTypeSymbol, NamedTypeSymbol))
+ End If
+
+ Return definition
End Function
Protected Overrides Sub EnqueueTypeSymbolInterfacesAndBaseTypes(typeDefsToSearch As Queue(Of TypeDefinitionHandle), typeSymbolsToSearch As Queue(Of TypeSymbol), typeSymbol As TypeSymbol)
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.vb
index 02e4d5e75dc07..8d6930537561a 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.vb
@@ -1187,7 +1187,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Try
For Each methodDef In [module].GetMethodsOfTypeOrThrow(_handle)
- If [module].ShouldImportMethod(methodDef, moduleSymbol.ImportOptions) Then
+ If [module].ShouldImportMethod(_handle, methodDef, moduleSymbol.ImportOptions) Then
methods.Add(methodDef, New PEMethodSymbol(moduleSymbol, Me, methodDef))
End If
Next
@@ -1207,8 +1207,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Dim methods = [module].GetPropertyMethodsOrThrow(propertyDef)
- Dim getMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, methods.Getter)
- Dim setMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, methods.Setter)
+ Dim getMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, _handle, methods.Getter)
+ Dim setMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, _handle, methods.Setter)
If (getMethod IsNot Nothing) OrElse (setMethod IsNot Nothing) Then
members.Add(PEPropertySymbol.Create(moduleSymbol, Me, propertyDef, getMethod, setMethod))
@@ -1230,9 +1230,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
Dim methods = [module].GetEventMethodsOrThrow(eventRid)
' NOTE: C# ignores all other accessors (most notably, raise/fire).
- Dim addMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, methods.Adder)
- Dim removeMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, methods.Remover)
- Dim raiseMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, methods.Raiser)
+ Dim addMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, _handle, methods.Adder)
+ Dim removeMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, _handle, methods.Remover)
+ Dim raiseMethod = GetAccessorMethod(moduleSymbol, methodHandleToSymbol, _handle, methods.Raiser)
' VB ignores events that do not have both Add and Remove.
If (addMethod IsNot Nothing) AndAlso (removeMethod IsNot Nothing) Then
@@ -1245,14 +1245,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Metadata.PE
End Try
End Sub
- Private Shared Function GetAccessorMethod(moduleSymbol As PEModuleSymbol, methodHandleToSymbol As Dictionary(Of MethodDefinitionHandle, PEMethodSymbol), methodDef As MethodDefinitionHandle) As PEMethodSymbol
+ Private Shared Function GetAccessorMethod(moduleSymbol As PEModuleSymbol, methodHandleToSymbol As Dictionary(Of MethodDefinitionHandle, PEMethodSymbol), typeDef As TypeDefinitionHandle, methodDef As MethodDefinitionHandle) As PEMethodSymbol
If methodDef.IsNil Then
Return Nothing
End If
Dim method As PEMethodSymbol = Nothing
Dim found As Boolean = methodHandleToSymbol.TryGetValue(methodDef, method)
- Debug.Assert(found OrElse Not moduleSymbol.Module.ShouldImportMethod(methodDef, moduleSymbol.ImportOptions))
+ Debug.Assert(found OrElse Not moduleSymbol.Module.ShouldImportMethod(typeDef, methodDef, moduleSymbol.ImportOptions))
Return method
End Function
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.vb b/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.vb
index 59ce74a4b4a2c..46e7c7e6a1bb2 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Retargeting/RetargetingSymbolTranslator.vb
@@ -884,6 +884,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
End Function
Public Function Retarget(method As MethodSymbol, retargetedMethodComparer As IEqualityComparer(Of MethodSymbol)) As MethodSymbol
+ Debug.Assert(method Is method.ConstructedFrom)
+
If method.ContainingModule Is Me.UnderlyingModule AndAlso method.IsDefinition Then
Return DirectCast(SymbolMap.GetOrAdd(method, _retargetingModule._createRetargetingMethod), RetargetingMethodSymbol)
End If
@@ -891,10 +893,26 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
Dim containingType = method.ContainingType
Dim retargetedType = Retarget(containingType, RetargetOptions.RetargetPrimitiveTypesByName)
+ If retargetedType Is containingType Then
+ Return method
+ End If
+
+ If Not containingType.IsDefinition Then
+ Debug.Assert(Not retargetedType.IsDefinition)
+
+ Dim retargetedDefinition = Retarget(method.OriginalDefinition, retargetedMethodComparer)
+
+ If retargetedDefinition Is Nothing Then
+ Return Nothing
+ End If
+
+ Return retargetedDefinition.AsMember(retargetedType)
+ End If
+
+ Debug.Assert(retargetedType.IsDefinition)
+
' NB: may return null if the method cannot be found in the retargeted type (e.g. removed in a subsequent version)
- Return If(retargetedType Is containingType,
- method,
- FindMethodInRetargetedType(method, retargetedType, retargetedMethodComparer))
+ Return FindMethodInRetargetedType(method, retargetedType, retargetedMethodComparer)
End Function
Private Function FindMethodInRetargetedType(method As MethodSymbol, retargetedType As NamedTypeSymbol, retargetedMethodComparer As IEqualityComparer(Of MethodSymbol)) As MethodSymbol
@@ -904,8 +922,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
Private Class RetargetedTypeMethodFinder
Inherits RetargetingSymbolTranslator
- Private Sub New(retargetingModule As RetargetingModuleSymbol)
+ Private ReadOnly _retargetedType As NamedTypeSymbol
+ Private ReadOnly _toFind As MethodSymbol
+
+ Private Sub New(retargetingModule As RetargetingModuleSymbol, retargetedType As NamedTypeSymbol, toFind As MethodSymbol)
MyBase.New(retargetingModule)
+
+ _retargetedType = retargetedType
+ _toFind = toFind
End Sub
Public Shared Function Find(
@@ -918,7 +942,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
Return Nothing
End If
- If Not method.IsGenericMethod Then
+ If Not method.IsGenericMethod AndAlso Not retargetedType.IsGenericType Then
Return FindWorker(translator, method, retargetedType, retargetedMethodComparer)
End If
@@ -926,9 +950,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
' among members of a type, constructed methods are never returned through GetMembers API.
Debug.Assert(method Is method.ConstructedFrom)
- ' A generic method needs special handling because its signature is very likely
- ' to refer to method's type parameters.
- Dim finder = New RetargetedTypeMethodFinder(translator._retargetingModule)
+ ' A generic method or a method in generic type needs special handling because its signature is very likely
+ ' to refer to method's or type's type parameters.
+ Dim finder = New RetargetedTypeMethodFinder(translator._retargetingModule, retargetedType, method)
Return FindWorker(finder, method, retargetedType, retargetedMethodComparer)
End Function
@@ -977,15 +1001,27 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols.Retargeting
End Function
Public Overrides Function Retarget(typeParameter As TypeParameterSymbol) As TypeParameterSymbol
- If typeParameter.ContainingModule Is Me.UnderlyingModule Then
- Return MyBase.Retarget(typeParameter)
+ If typeParameter.TypeParameterKind = TypeParameterKind.Method Then
+ Debug.Assert(typeParameter.ContainingSymbol Is _toFind)
+
+ ' The method symbol we are building will be using IndexedTypeParameterSymbols as
+ ' its type parameters, therefore, we should return them here as well.
+ Return IndexedTypeParameterSymbol.GetTypeParameter(typeParameter.Ordinal)
End If
- Debug.Assert(typeParameter.TypeParameterKind = TypeParameterKind.Method)
+ Dim containingType As NamedTypeSymbol = _toFind.ContainingType
+ Dim retargetedContainingType As NamedTypeSymbol = _retargetedType
+
+ Do
+ If containingType Is typeParameter.ContainingSymbol Then
+ Return retargetedContainingType.TypeParameters(typeParameter.Ordinal)
+ End If
+
+ containingType = containingType.ContainingType
+ retargetedContainingType = retargetedContainingType.ContainingType
+ Loop While containingType IsNot Nothing
- ' The method symbol we are building will be using IndexedTypeParameterSymbols as
- ' its type parameters, therefore, we should return them here as well.
- Return IndexedTypeParameterSymbol.GetTypeParameter(typeParameter.Ordinal)
+ Throw ExceptionUtilities.Unreachable
End Function
End Class
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb
index 85122d83b1244..d7a9a545059da 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/SynthesizedSymbols/SynthesizedClonedTypeParameterSymbol.vb
@@ -45,6 +45,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
_correspondingMethodTypeParameter = correspondingMethodTypeParameter
_name = name
_typeMapFactory = typeMapFactory
+
+ Debug.Assert(Me.TypeParameterKind = If(TypeOf Me.ContainingSymbol Is MethodSymbol, TypeParameterKind.Method,
+ If(TypeOf Me.ContainingSymbol Is NamedTypeSymbol, TypeParameterKind.Type,
+ TypeParameterKind.Cref)),
+ $"Container is {Me.ContainingSymbol?.Kind}, TypeParameterKind is {Me.TypeParameterKind}")
End Sub
Public Overrides ReadOnly Property TypeParameterKind As TypeParameterKind
diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb b/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb
index c9cc775bfcd3d..a98e82937f542 100644
--- a/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb
+++ b/src/Compilers/VisualBasic/Portable/Symbols/Wrapped/WrappedTypeParameterSymbol.vb
@@ -88,6 +88,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
Public Sub New(underlyingTypeParameter As TypeParameterSymbol)
Debug.Assert(underlyingTypeParameter IsNot Nothing)
Me._underlyingTypeParameter = underlyingTypeParameter
+
+ Debug.Assert(Me.TypeParameterKind = If(TypeOf Me.ContainingSymbol Is MethodSymbol, TypeParameterKind.Method,
+ If(TypeOf Me.ContainingSymbol Is NamedTypeSymbol, TypeParameterKind.Type,
+ TypeParameterKind.Cref)),
+ $"Container is {Me.ContainingSymbol?.Kind}, TypeParameterKind is {Me.TypeParameterKind}")
End Sub
Public Overrides Function GetDocumentationCommentXml(Optional preferredCulture As CultureInfo = Nothing, Optional expandIncludes As Boolean = False, Optional cancellationToken As CancellationToken = Nothing) As String
diff --git a/src/Compilers/VisualBasic/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.vb b/src/Compilers/VisualBasic/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.vb
index 8de7ec862a34c..b18da30f4d268 100644
--- a/src/Compilers/VisualBasic/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.vb
+++ b/src/Compilers/VisualBasic/Test/Emit/Attributes/InternalsVisibleToAndStrongNameTests.vb
@@ -2309,4 +2309,105 @@ BC37254: Public sign was specified and requires a public key, but no public key
)
End Sub
+
+
+
+ Public Sub IVT_Circularity(parseOptions As VisualBasicParseOptions)
+ Dim other As VisualBasicCompilation = CreateCompilation(
+
+
+Public MustInherit Class TestBaseClass
+ Friend Overridable ReadOnly Property SupportSvgImages As Object
+ Get
+ Return True
+ End Get
+ End Property
+End Class
+]]>
+
+, options:=TestOptions.SigningReleaseDll, parseOptions:=parseOptions)
+
+ other.VerifyDiagnostics()
+
+ Dim c2 As VisualBasicCompilation = CreateCompilation(
+
+
+
+
+]]>
+
+, {New VisualBasicCompilationReference(other)}, options:=TestOptions.SigningReleaseDll, parseOptions:=parseOptions)
+
+ c2.AssertTheseDiagnostics(
+ ~~~~~~
+]]>)
+ End Sub
+
+
+
+
+ Public Sub IVT_Circularity_AttributeReferencesProperty(parseOptions As VisualBasicParseOptions)
+ Dim other As VisualBasicCompilation = CreateCompilation(
+
+
+Public MustInherit Class TestBaseClass
+ Friend Overridable ReadOnly Property SupportSvgImages As Object
+ Get
+ Return True
+ End Get
+ End Property
+End Class
+
+Public Class MyAttribute
+ Inherits System.Attribute
+
+ Public Sub New(s As String)
+ End Sub
+End Class
+]]>
+
+, options:=TestOptions.SigningReleaseDll, parseOptions:=parseOptions)
+
+ other.VerifyDiagnostics()
+
+ Dim c2 As VisualBasicCompilation = CreateCompilation(
+
+
+
+
+]]>
+
+, {New VisualBasicCompilationReference(other)}, options:=TestOptions.SigningReleaseDll, parseOptions:=parseOptions)
+
+ c2.AssertNoDiagnostics()
+ End Sub
+
End Class
diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb
index 1e1e3abbe0b7d..d1a70a3446e3e 100644
--- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb
+++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueClosureTests.vb
@@ -222,7 +222,7 @@ End Class
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Sub
@@ -435,9 +435,9 @@ End Module
Row(7, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(11, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(18, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(19, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(20, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Sub
diff --git a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb
index 49aca9d89d25c..fc4bd161e65f5 100644
--- a/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb
+++ b/src/Compilers/VisualBasic/Test/Emit/Emit/EditAndContinue/EditAndContinueStateMachineTests.vb
@@ -911,7 +911,8 @@ End Class
Using md1 = diff1.GetMetadata()
CheckEncLogDefinitions(md1.Reader,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
- Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default))
+ Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
End Using
End Sub
@@ -958,7 +959,9 @@ End Class
Using md1 = diff1.GetMetadata()
CheckEncLogDefinitions(md1.Reader,
Row(3, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
- Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default))
+ Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
End Using
End Sub
@@ -1038,15 +1041,15 @@ End Class
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(19, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(20, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(21, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(22, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(23, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(24, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(25, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(26, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(27, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(17, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
End Using
End Sub
@@ -1101,9 +1104,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1250,9 +1253,9 @@ End Class
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1500,9 +1503,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1614,9 +1617,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1731,9 +1734,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1844,9 +1847,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -1987,9 +1990,9 @@ End Class
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(14, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -2134,9 +2137,9 @@ End Class
Row(4, TableIndex.StandAloneSig, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -2296,9 +2299,9 @@ End Class
Row(7, TableIndex.Field, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -2461,9 +2464,9 @@ End Class
Row(7, TableIndex.Field, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -2622,9 +2625,9 @@ End Class
Row(6, TableIndex.Field, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Using
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
@@ -2930,12 +2933,12 @@ End Class
Row(3, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(19, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(20, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(21, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(22, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(23, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(24, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
diff1.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
{
@@ -3048,9 +3051,9 @@ End Class
Row(21, TableIndex.Field, EditAndContinueOperation.Default),
Row(2, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(25, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(26, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(27, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(4, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(5, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
diff2.VerifyIL("C.VB$StateMachine_1_F.MoveNext()", "
{
@@ -3167,12 +3170,12 @@ End Class
Row(4, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(28, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(29, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(30, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(31, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(32, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(33, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(17, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Sub
@@ -3444,12 +3447,12 @@ End Class
Row(6, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(19, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(20, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(21, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(22, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(23, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(24, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
diff1.VerifyIL("C.VB$StateMachine_4_F.MoveNext()", "
{
@@ -3603,9 +3606,9 @@ End Class
Row(15, TableIndex.Field, EditAndContinueOperation.Default),
Row(5, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(9, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(25, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(26, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(27, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(6, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(7, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(13, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
diff2.VerifyIL("C.VB$StateMachine_4_F.MoveNext()", "
{
@@ -3765,12 +3768,12 @@ End Class
Row(7, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(12, TableIndex.MethodDef, EditAndContinueOperation.Default),
Row(15, TableIndex.MethodDef, EditAndContinueOperation.Default),
- Row(28, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(29, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(30, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(31, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(32, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
- Row(33, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
+ Row(9, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(10, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(11, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(12, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(15, TableIndex.CustomAttribute, EditAndContinueOperation.Default),
+ Row(17, TableIndex.CustomAttribute, EditAndContinueOperation.Default))
End Sub
diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaTests.vb
index 070a4891db66b..98ce6ab7d33a6 100644
--- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaTests.vb
+++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/LambdaTests.vb
@@ -2164,5 +2164,223 @@ In getter
]]>)
End Sub
+
+
+ Public Sub Issue53593_1()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Public a, b As New C1((Function(n) n + 1)(1))
+
+ Shared Sub Main()
+ Dim x as New C0()
+ System.Console.Write(x.a.F1)
+ System.Console.Write(x.b.F1)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="22")
+ End Sub
+
+
+
+ Public Sub Issue53593_2()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Shared Sub Main()
+ Dim a, b As New C1((Function(n) n + 1)(1))
+ System.Console.Write(a.F1)
+ System.Console.Write(b.F1)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="22")
+ End Sub
+
+
+
+ Public Sub Issue53593_3()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Public a, b As New C1((Function(n) n + 1)(1))
+
+ Shared Sub Main()
+ Dim x as New C0()
+ System.Console.Write(x.a.F1)
+ System.Console.Write(x.b.F1)
+
+ x = New C0(True)
+ System.Console.Write(x.a.F1)
+ System.Console.Write(x.b.F1)
+ End Sub
+
+ Sub New()
+ End Sub
+
+ Sub New(b as Boolean)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="2222")
+ End Sub
+
+
+
+ Public Sub Issue53593_4()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Public a, b As New C1((Function(n1) (Function(n2) n2 + 1)(n1))(1))
+
+ Shared Sub Main()
+ Dim x as New C0()
+ System.Console.Write(x.a.F1)
+ System.Console.Write(x.b.F1)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="22")
+ End Sub
+
+
+
+ Public Sub Issue53593_5()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Shared Sub Main()
+ Test(Of Object)()
+ End Sub
+
+ Shared Sub Test(Of T)()
+ Dim a, b As New C1((Function(n)
+ Dim x as T
+ x = Nothing
+ Return CObj(x) + n + 1
+ End Function)(1))
+ System.Console.Write(a.F1)
+ System.Console.Write(b.F1)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="22")
+ End Sub
+
+
+
+ Public Sub Issue53593_6()
+
+ Dim compilationDef =
+
+
+Public Class C0
+
+ Public WithEvents a, b As New C1((Function(n) n + 1)(1))
+
+ Shared Sub Main()
+ Dim x as New C0()
+ System.Console.Write(x.a.F1)
+ System.Console.Write(x.b.F1)
+ End Sub
+End Class
+
+Public Class C1
+
+ Public F1 as Integer
+
+ Sub New(a As Integer)
+ F1 = a
+ End Sub
+End Class
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithMscorlib40AndVBRuntime(compilationDef, TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation, expectedOutput:="22")
+ End Sub
+
End Class
End Namespace
diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb
index 496041616321f..7b7ddd5713b60 100644
--- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb
+++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/UserDefinedBinaryOperators.vb
@@ -910,7 +910,7 @@ op_BitwiseOr
End Sub
- Public Sub OperatorMapping_BothSignedAndUnsignedShift()
+ Public Sub OperatorMapping_BothSignedAndUnsignedShift_01()
Dim ilSource =
> 2 << 3
+ End Sub
+End Module
+ ]]>
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithCustomILSource(compilationDef, ilSource.Value, includeVbRuntime:=True, options:=TestOptions.ReleaseExe)
+
+ Dim verifier = CompileAndVerify(compilation,
+ expectedOutput:=
+ )
+ End Sub
+
+
+ Public Sub OperatorMapping_BothSignedAndUnsignedShift_02()
+
+ Dim ilSource =
+
+
+ Dim compilationDef =
+
+
+ Public Sub Does_Not_Enable_Incremental_Generators()
+
+ Dim parseOptions = TestOptions.Regular
+ Dim compilation As Compilation = GetCompilation(parseOptions)
+ Dim testGenerator As VBIncrementalGenerator = New VBIncrementalGenerator()
+ Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(New IncrementalGeneratorWrapper(testGenerator)), parseOptions:=parseOptions)
+
+ Dim outputCompilation As Compilation = Nothing
+ Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing
+ driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics)
+ outputDiagnostics.Verify()
+
+ Assert.Equal(1, outputCompilation.SyntaxTrees.Count())
+ Assert.Equal(compilation, compilation)
+ Assert.False(testGenerator._initialized)
+ End Sub
+
+
+ Public Sub Does_Not_Prefer_Incremental_Generators()
+
+ Dim parseOptions = TestOptions.Regular
+ Dim compilation As Compilation = GetCompilation(parseOptions)
+ Dim testGenerator As VBIncrementalAndSourceGenerator = New VBIncrementalAndSourceGenerator()
+ Dim driver As GeneratorDriver = VisualBasicGeneratorDriver.Create(ImmutableArray.Create(Of ISourceGenerator)(testGenerator), parseOptions:=parseOptions)
+
+ Dim outputCompilation As Compilation = Nothing
+ Dim outputDiagnostics As ImmutableArray(Of Diagnostic) = Nothing
+ driver.RunGeneratorsAndUpdateCompilation(compilation, outputCompilation, outputDiagnostics)
+ outputDiagnostics.Verify()
+
+ Assert.Equal(1, outputCompilation.SyntaxTrees.Count())
+ Assert.Equal(compilation, compilation)
+ Assert.False(testGenerator._initialized)
+ Assert.True(testGenerator._sourceInitialized)
+ Assert.True(testGenerator._sourceExecuted)
+ End Sub
Shared Function GetCompilation(parseOptions As VisualBasicParseOptions, Optional source As String = "") As Compilation
If (String.IsNullOrWhiteSpace(source)) Then
@@ -348,5 +385,39 @@ End Class
End Class
+
+ Friend Class VBIncrementalGenerator
+ Implements IIncrementalGenerator
+
+ Public _initialized As Boolean
+
+ Public Sub Initialize(context As IncrementalGeneratorInitializationContext) Implements IIncrementalGenerator.Initialize
+ _initialized = True
+ End Sub
+ End Class
+
+
+ Friend Class VBIncrementalAndSourceGenerator
+ Implements IIncrementalGenerator
+ Implements ISourceGenerator
+
+ Public _initialized As Boolean
+ Public _sourceInitialized As Boolean
+ Public _sourceExecuted As Boolean
+
+ Public Sub Initialize(context As IncrementalGeneratorInitializationContext) Implements IIncrementalGenerator.Initialize
+ _initialized = True
+ End Sub
+
+ Public Sub Initialize(context As GeneratorInitializationContext) Implements ISourceGenerator.Initialize
+ _sourceInitialized = True
+ End Sub
+
+ Public Sub Execute(context As GeneratorExecutionContext) Implements ISourceGenerator.Execute
+ _sourceExecuted = True
+ End Sub
+
+
+ End Class
End Namespace
diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb
index 3003d9d737eb9..87e3287ef704a 100644
--- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb
+++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Metadata/PE/LoadingMethods.vb
@@ -965,5 +965,124 @@ BC30390: 'C2.Private Overloads Sub M2()' is not accessible in this context becau
]]>)
End Sub
+
+
+ Public Sub TestAmbiguousImplementationMethod()
+
+ Dim ilSource =
+
+{
+ // Methods
+ .method public hidebysig abstract virtual
+ void Method (
+ int32 i
+ ) cil managed
+ {
+ } // end of method Interface`2::Method
+
+ .method public hidebysig abstract virtual
+ void Method (
+ !T i
+ ) cil managed
+ {
+ } // end of method Interface`2::Method
+
+ .method public hidebysig abstract virtual
+ void Method (
+ !U i
+ ) cil managed
+ {
+ } // end of method Interface`2::Method
+
+} // end of class Interface`2
+
+.class public auto ansi beforefieldinit Base`1
+ extends [mscorlib]System.Object
+ implements class Interface`2
+{
+ // Methods
+ .method public hidebysig newslot virtual
+ void Method (
+ int32 i
+ ) cil managed
+ {
+ .override method instance void class Interface`2::Method(int32)
+ // Method begins at RVA 0x2050
+ // Code size 2 (0x2)
+ .maxstack 8
+
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method Base`1::Method
+
+ .method public hidebysig newslot virtual
+ void Method (
+ !T i
+ ) cil managed
+ {
+ .override method instance void class Interface`2::Method(!0)
+ .override method instance void class Interface`2::Method(!1)
+ // Method begins at RVA 0x2050
+ // Code size 2 (0x2)
+ .maxstack 8
+
+ IL_0000: nop
+ IL_0001: ret
+ } // end of method Base`1::Method
+
+ .method public hidebysig specialname rtspecialname
+ instance void .ctor () cil managed
+ {
+ // Method begins at RVA 0x2053
+ // Code size 8 (0x8)
+ .maxstack 8
+
+ IL_0000: ldarg.0
+ IL_0001: call instance void [mscorlib]System.Object::.ctor()
+ IL_0006: nop
+ IL_0007: ret
+ } // end of method Base`1::.ctor
+
+} // end of class Base`1
+]]>
+
+ Dim compilationDef =
+
+
+Option Strict Off
+
+Imports System
+
+Module Module1
+ Sub Main()
+ End Sub
+End Module
+
+
+
+ Dim compilation = CompilationUtils.CreateCompilationWithCustomILSource(compilationDef, ilSource.Value, includeVbRuntime:=True, options:=TestOptions.ReleaseExe)
+
+ Dim b = compilation.GlobalNamespace.GetTypeMember("Base")
+ Dim bI = b.Interfaces().Single()
+ Dim biMethods = bI.GetMembers()
+
+ Assert.Equal("Sub [Interface](Of T, U).Method(i As System.Int32)", biMethods(0).OriginalDefinition.ToTestDisplayString())
+ Assert.Equal("Sub [Interface](Of T, U).Method(i As T)", biMethods(1).OriginalDefinition.ToTestDisplayString())
+ Assert.Equal("Sub [Interface](Of T, U).Method(i As U)", biMethods(2).OriginalDefinition.ToTestDisplayString())
+
+ Dim bMethods = b.GetMembers()
+
+ Assert.Equal("Sub Base(Of T).Method(i As System.Int32)", bMethods(0).ToTestDisplayString())
+ Assert.Equal("Sub Base(Of T).Method(i As T)", bMethods(1).ToTestDisplayString())
+
+ Dim bM1Impl = DirectCast(bMethods(0), MethodSymbol).ExplicitInterfaceImplementations
+ Dim bM2Impl = DirectCast(bMethods(1), MethodSymbol).ExplicitInterfaceImplementations
+ Assert.Equal(biMethods(0), bM1Impl.Single())
+
+ Assert.Equal(2, bM2Impl.Length)
+ Assert.Equal(biMethods(1), bM2Impl(0))
+ Assert.Equal(biMethods(2), bM2Impl(1))
+ End Sub
End Class
End Namespace
diff --git a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb
index b4380d1e3bf67..b61ce12c60488 100644
--- a/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb
+++ b/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb
@@ -3255,6 +3255,40 @@ End Class
Assert.True(DirectCast(cs, INamedTypeSymbol).IsSerializable)
End Sub
+
+ Public Sub ExplicitInterfaceImplementationRetargetingGenericType()
+ Dim source1 = "
+Public Class C1(Of T)
+ Public Interface I1
+ Sub M(x As T)
+ End Interface
+End Class
+"
+ Dim ref1 = CreateEmptyCompilation("").ToMetadataReference()
+ Dim compilation1 = CreateCompilation(source1, references:={ref1})
+
+ Dim source2 = "
+Public Class C2(Of U)
+ Implements C1(Of U).I1
+
+ Sub M(x As U) Implements C1(Of U).I1.M
+ End Sub
+End Class
+"
+ Dim compilation2 = CreateCompilation(source2, references:={compilation1.ToMetadataReference(), ref1, CreateEmptyCompilation("").ToMetadataReference()})
+
+ Dim compilation3 = CreateCompilation("", references:={compilation1.ToMetadataReference(), compilation2.ToMetadataReference()})
+
+ Assert.NotSame(compilation2.GetTypeByMetadataName("C1`1"), compilation3.GetTypeByMetadataName("C1`1"))
+
+ Dim c2 = compilation3.GetTypeByMetadataName("C2`1")
+ Assert.IsType(Of RetargetingNamedTypeSymbol)(c2)
+
+ Dim m = c2.GetMethod("M")
+
+ Assert.Equal(c2.Interfaces().Single().GetMethod("M"), m.ExplicitInterfaceImplementations.Single())
+ End Sub
+
End Class
#End If
diff --git a/src/EditorFeatures/CSharp/CSharpEditorResources.resx b/src/EditorFeatures/CSharp/CSharpEditorResources.resx
index 0498beacc31e0..3709e7f0ef1cb 100644
--- a/src/EditorFeatures/CSharp/CSharpEditorResources.resx
+++ b/src/EditorFeatures/CSharp/CSharpEditorResources.resx
@@ -437,4 +437,7 @@
Outside namespace
+
+ Prefer 'null' check over type check
+
\ No newline at end of file
diff --git a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs
index 5d42e7a200b3e..7cd49b0f0a6a5 100644
--- a/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs
+++ b/src/EditorFeatures/CSharp/CompleteStatement/CompleteStatementCommandHandler.cs
@@ -223,6 +223,7 @@ private static bool MoveCaretToSemicolonPosition(
{
return MoveCaretToFinalPositionInStatement(speculative, currentNode, args, originalCaret, caret, true);
}
+
return false;
}
else if (syntaxFacts.IsStatement(currentNode)
diff --git a/src/EditorFeatures/CSharp/DecompiledSource/AssemblyResolver.cs b/src/EditorFeatures/CSharp/DecompiledSource/AssemblyResolver.cs
index 41df9fab1d1dc..fa8faed093731 100644
--- a/src/EditorFeatures/CSharp/DecompiledSource/AssemblyResolver.cs
+++ b/src/EditorFeatures/CSharp/DecompiledSource/AssemblyResolver.cs
@@ -71,6 +71,7 @@ public PEFile Resolve(IAssemblyReference name)
{
Log(CSharpEditorResources.WARN_Version_mismatch_Expected_0_Got_1, name.Version, assemblies[0].Identity.Version);
}
+
return MakePEFile(assemblies[0]);
}
diff --git a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs
index bce834f0c12ec..8e4de95a1439a 100644
--- a/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs
+++ b/src/EditorFeatures/CSharp/EditorConfigSettings/DataProvider/CodeStyle/CSharpCodeStyleSettingsProvider.cs
@@ -101,6 +101,10 @@ private static IEnumerable GetNullCheckingCodeStyleOptions(Ana
description: CSharpEditorResources.Prefer_conditional_delegate_call,
editorConfigOptions: editorConfigOptions,
visualStudioOptions: visualStudioOptions, updater: updaterService);
+ yield return CodeStyleSetting.Create(option: CSharpCodeStyleOptions.PreferNullCheckOverTypeCheck,
+ description: CSharpEditorResources.Prefer_null_check_over_type_check,
+ editorConfigOptions: editorConfigOptions,
+ visualStudioOptions: visualStudioOptions, updater: updaterService);
}
private static IEnumerable GetModifierCodeStyleOptions(AnalyzerConfigOptions editorConfigOptions, OptionSet visualStudioOptions, OptionUpdater updaterService)
diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs
index 8ab7f7733c7a3..223cada0e0768 100644
--- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs
+++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/ReturnStatementHighlighter.cs
@@ -63,6 +63,7 @@ private void HighlightRelatedKeywords(SyntaxNode node, List spans)
if (!child.AsNode().IsReturnableConstruct())
HighlightRelatedKeywords(child.AsNode(), spans);
}
+
break;
}
}
diff --git a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs
index 42f0e62caf917..dfffb011685b0 100644
--- a/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs
+++ b/src/EditorFeatures/CSharp/Highlighting/KeywordHighlighters/YieldStatementHighlighter.cs
@@ -69,6 +69,7 @@ private void HighlightRelatedKeywords(SyntaxNode node, List spans)
HighlightRelatedKeywords(child.AsNode(), spans);
}
}
+
break;
}
}
diff --git a/src/EditorFeatures/CSharp/InheritanceMargin/CSharpInheritanceMarginService.cs b/src/EditorFeatures/CSharp/InheritanceMargin/CSharpInheritanceMarginService.cs
index 02518184e9a8c..c1b8330890e7a 100644
--- a/src/EditorFeatures/CSharp/InheritanceMargin/CSharpInheritanceMarginService.cs
+++ b/src/EditorFeatures/CSharp/InheritanceMargin/CSharpInheritanceMarginService.cs
@@ -43,7 +43,9 @@ protected override ImmutableArray GetMembers(IEnumerable
SyntaxKind.MethodDeclaration,
SyntaxKind.PropertyDeclaration,
SyntaxKind.EventDeclaration,
- SyntaxKind.IndexerDeclaration))
+ SyntaxKind.IndexerDeclaration,
+ SyntaxKind.OperatorDeclaration,
+ SyntaxKind.ConversionOperatorDeclaration))
{
builder.Add(member);
}
@@ -69,6 +71,8 @@ protected override SyntaxToken GetDeclarationToken(SyntaxNode declarationNode)
VariableDeclaratorSyntax variableDeclaratorNode => variableDeclaratorNode.Identifier,
TypeDeclarationSyntax baseTypeDeclarationNode => baseTypeDeclarationNode.Identifier,
IndexerDeclarationSyntax indexerDeclarationNode => indexerDeclarationNode.ThisKeyword,
+ OperatorDeclarationSyntax operatorDeclarationNode => operatorDeclarationNode.OperatorToken,
+ ConversionOperatorDeclarationSyntax conversionOperatorDeclarationNode => conversionOperatorDeclarationNode.Type.GetFirstToken(),
// Shouldn't reach here since the input declaration nodes are coming from GetMembers() method above
_ => throw ExceptionUtilities.UnexpectedValue(declarationNode),
};
diff --git a/src/EditorFeatures/CSharp/Microsoft.CodeAnalysis.CSharp.EditorFeatures.csproj b/src/EditorFeatures/CSharp/Microsoft.CodeAnalysis.CSharp.EditorFeatures.csproj
index 37cc1a409ee8d..71eb76a34f9e7 100644
--- a/src/EditorFeatures/CSharp/Microsoft.CodeAnalysis.CSharp.EditorFeatures.csproj
+++ b/src/EditorFeatures/CSharp/Microsoft.CodeAnalysis.CSharp.EditorFeatures.csproj
@@ -6,7 +6,7 @@
Microsoft.CodeAnalysis.Editor.CSharp
netcoreapp3.1;netstandard2.0
true
- partial
+ partial
true
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf
index 08408a67dd409..9d05d7a21856f 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.cs.xlf
@@ -372,6 +372,11 @@
Preferovat lokální funkci před anonymní funkcí
+
+
+ Prefer 'null' check over type check
+
+
Upřednostňovat porovnávání vzorů
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf
index f602885cf3ed3..438c2f31e1494 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.de.xlf
@@ -372,6 +372,11 @@
Lokale Funktion gegenüber anonymer Funktion bevorzugen
+
+
+ Prefer 'null' check over type check
+
+
Musterabgleich bevorzugen
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf
index cf02c7fb87f3d..5c28c9491507e 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.es.xlf
@@ -372,6 +372,11 @@
Preferir una función local frente a una función anónima
+
+
+ Prefer 'null' check over type check
+
+
Preferir coincidencia de patrones
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf
index e407bf2c439e1..1973eec00c4e4 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.fr.xlf
@@ -372,6 +372,11 @@
Préférer une fonction locale à une fonction anonyme
+
+
+ Prefer 'null' check over type check
+
+
Préférer les critères spéciaux
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf
index 410040f6b23a0..2aa73552e0c36 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.it.xlf
@@ -372,6 +372,11 @@
Preferisci la funzione locale a quella anonima
+
+
+ Prefer 'null' check over type check
+
+
Preferisci i criteri di ricerca
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf
index 2276f9274aa04..e64a9efb093c3 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ja.xlf
@@ -372,6 +372,11 @@
匿名関数よりローカル関数を優先します
+
+
+ Prefer 'null' check over type check
+
+
パターン マッチングを優先する
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf
index 44dd19bfe303e..f9cf0e5c4d7e2 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ko.xlf
@@ -372,6 +372,11 @@
익명 함수보다 로컬 함수 선호
+
+
+ Prefer 'null' check over type check
+
+
패턴 일치 선호
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf
index 3dc3b375fdf0d..486b71d2a215c 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pl.xlf
@@ -372,6 +372,11 @@
Preferuj funkcję lokalną zamiast funkcji anonimowej
+
+
+ Prefer 'null' check over type check
+
+
Preferuj dopasowywanie do wzorca
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf
index 9003529dc846b..278d4c584974c 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.pt-BR.xlf
@@ -372,6 +372,11 @@
Preferir usar função anônima em vez de local
+
+
+ Prefer 'null' check over type check
+
+
Preferir a correspondência de padrões
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf
index faa1c9676dd99..51902f502a6c2 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.ru.xlf
@@ -372,6 +372,11 @@
Предпочитать локальную функцию анонимной функции
+
+
+ Prefer 'null' check over type check
+
+
Предпочитать соответствие шаблону
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf
index c41985167cadc..6ff776740d16b 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.tr.xlf
@@ -372,6 +372,11 @@
Anonim işlevler yerine yerel işlevleri tercih et
+
+
+ Prefer 'null' check over type check
+
+
Desen eşleştirmeyi tercih et
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf
index cea90185fea94..57f7b1c1bca0b 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hans.xlf
@@ -372,6 +372,11 @@
首选本地函数而不是匿名函数
+
+
+ Prefer 'null' check over type check
+
+
首选模式匹配
diff --git a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf
index 13988058c5938..4b7d00fbb0ef3 100644
--- a/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf
+++ b/src/EditorFeatures/CSharp/xlf/CSharpEditorResources.zh-Hant.xlf
@@ -372,6 +372,11 @@
使用區域函式優先於匿名函式
+
+
+ Prefer 'null' check over type check
+
+
建議使用模式比對
diff --git a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
index 3f5f22412b791..d3961df775dbc 100644
--- a/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
+++ b/src/EditorFeatures/CSharpTest/AddParameter/AddParameterTests.cs
@@ -2849,5 +2849,59 @@ void Test()
}
}");
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
+ [WorkItem(54408, "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, Trait(Traits.Feature, Traits.Features.CodeActionsAddParameter)]
+ [WorkItem(54408, "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));
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/CodeActions/AddAwait/AddAwaitTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/AddAwait/AddAwaitTests.cs
index 8a7547abf1828..977226441d9ac 100644
--- a/src/EditorFeatures/CSharpTest/CodeActions/AddAwait/AddAwaitTests.cs
+++ b/src/EditorFeatures/CSharpTest/CodeActions/AddAwait/AddAwaitTests.cs
@@ -1448,5 +1448,21 @@ async Task A()
return await (null as Task); }
}");
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsAddAwait)]
+ [WorkItem(1345322, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1345322")]
+ public async Task TestOnTaskTypeItself()
+ {
+ await TestMissingAsync(
+@"using System.Threading.Tasks;
+
+class Program
+{
+ static async [||]Task Main(string[] args)
+ {
+ }
+}
+");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceParameter/IntroduceParameterTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceParameter/IntroduceParameterTests.cs
index fea96d9c25894..df4d41e43624a 100644
--- a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceParameter/IntroduceParameterTests.cs
+++ b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceParameter/IntroduceParameterTests.cs
@@ -1775,5 +1775,50 @@ void M1()
}";
await TestInRegularAndScriptAsync(code, expected, index: 0);
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceParameter)]
+ public async Task TestHighlightReturnType()
+ {
+ var code =
+@"using System;
+class TestClass
+{
+ [|int|] M(int x)
+ {
+ return x;
+ }
+
+ void M1()
+ {
+ M(5);
+ }
+}";
+ await TestMissingInRegularAndScriptAsync(code);
+ }
+
+ [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceParameter)]
+ public async Task TestTypeOfOnString()
+ {
+ var code =
+@"using System;
+class TestClass
+{
+ void M()
+ {
+ var x = [|typeof(string);|]
+ }
+}";
+
+ var expected =
+@"using System;
+class TestClass
+{
+ void M(Type x)
+ {
+ }
+}";
+
+ await TestInRegularAndScriptAsync(code, expected, index: 0);
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveToNewFile.cs b/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveToNewFile.cs
index 2795b666bef30..c3a43618a02c9 100644
--- a/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveToNewFile.cs
+++ b/src/EditorFeatures/CSharpTest/CodeActions/MoveType/MoveTypeTests.MoveToNewFile.cs
@@ -1408,5 +1408,51 @@ record CacheContext(String Message);
await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText);
}
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
+ public async Task MoveClassInTopLevelStatements()
+ {
+ var code = @"
+using ConsoleApp1;
+using System;
+
+var c = new C();
+Console.WriteLine(c.Hello);
+
+class [||]C
+{
+ public string Hello => ""Hello"";
+}";
+
+ var codeAfterMove = @"
+using ConsoleApp1;
+using System;
+
+var c = new C();
+Console.WriteLine(c.Hello);
+";
+
+ var expectedDocumentName = "C.cs";
+ var destinationDocumentText = @"class C
+{
+ public string Hello => ""Hello"";
+}";
+
+ await TestMoveTypeToNewFileAsync(code, codeAfterMove, expectedDocumentName, destinationDocumentText);
+ }
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.CodeActionsMoveType)]
+ public async Task MissingInTopLevelStatementsOnly()
+ {
+ var code = @"
+using ConsoleApp1;
+using System;
+
+var c = new object();
+[||]Console.WriteLine(c.ToString());
+";
+
+ await TestMissingAsync(code);
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ConversionCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ConversionCompletionProviderTests.cs
index f25ebc09047f0..8caf3f8b9b40d 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ConversionCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/ConversionCompletionProviderTests.cs
@@ -1651,6 +1651,43 @@ public static void Main()
}
}
}
+");
+ }
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47511, "https://github.com/dotnet/roslyn/issues/47511")]
+ public async Task ExplicitUserDefinedConversionNullForgivingOperatorHandling()
+ {
+ await VerifyCustomCommitProviderAsync(@"
+#nullable enable
+
+public class C {
+ public static explicit operator int(C c) => 0;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var i = c!.$$
+ }
+}
+", "int", @"
+#nullable enable
+
+public class C {
+ public static explicit operator int(C c) => 0;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var i = ((int)c!)$$
+ }
+}
");
}
}
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/IndexerCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/IndexerCompletionProviderTests.cs
index 9af45df20124e..8fd6906bd669d 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/IndexerCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/IndexerCompletionProviderTests.cs
@@ -498,5 +498,44 @@ await VerifyItemInEditorBrowsableContextsAsync(
sourceLanguage: LanguageNames.CSharp,
referencedLanguage: LanguageNames.CSharp);
}
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47511, "https://github.com/dotnet/roslyn/issues/47511")]
+ public async Task IndexerNullForgivingOperatorHandling()
+ {
+ await VerifyCustomCommitProviderAsync(@"
+#nullable enable
+
+public class C
+{
+ public int this[int i] => i;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var i = c!.$$
+ }
+}
+", "this", @"
+#nullable enable
+
+public class C
+{
+ public int this[int i] => i;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var i = c![$$]
+ }
+}
+");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OperatorCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OperatorCompletionProviderTests.cs
index 12165d91daa90..6776e7693a4f0 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OperatorCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/OperatorCompletionProviderTests.cs
@@ -832,5 +832,44 @@ await VerifyItemInEditorBrowsableContextsAsync(
referencedLanguage: LanguageNames.CSharp,
hideAdvancedMembers: true);
}
+
+ [WpfFact, Trait(Traits.Feature, Traits.Features.Completion)]
+ [WorkItem(47511, "https://github.com/dotnet/roslyn/issues/47511")]
+ public async Task OperatorBinaryNullForgivingHandling()
+ {
+ await VerifyCustomCommitProviderAsync(@"
+#nullable enable
+
+public class C
+{
+ public static C operator +(C a, C b) => default;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var _ = c!.$$
+ }
+}
+", "+", @"
+#nullable enable
+
+public class C
+{
+ public static C operator +(C a, C b) => default;
+}
+
+public class Program
+{
+ public static void Main()
+ {
+ C? c = null;
+ var _ = c! + $$
+ }
+}
+");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs
index 339f971c62b2a..31cbca9838720 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SnippetCompletionProviderTests.cs
@@ -78,6 +78,10 @@ public async Task SnippetsNotInPreProcessorContextDirectiveNameAlreadyTyped()
public async Task ShowRegionSnippetWithHashRTyped()
=> await VerifyItemExistsAsync(@"#r$$", MockSnippetInfoService.PreProcessorSnippetShortcut.Substring(1), sourceCodeKind: SourceCodeKind.Regular);
+ [Fact, Trait(Traits.Feature, Traits.Features.Completion)]
+ public async Task SnippetsInLineSpanDirective()
+ => await VerifyItemIsAbsentAsync(@"#line (1, 2) - (3, 4) $$", MockSnippetInfoService.PreProcessorSnippetShortcut, sourceCodeKind: SourceCodeKind.Regular);
+
[WorkItem(968256, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/968256")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task ShowSnippetsFromOtherContext()
diff --git a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs
index 01a35d5e86898..ae3decc2ed975 100644
--- a/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/Completion/CompletionProviders/SymbolCompletionProviderTests.cs
@@ -8070,6 +8070,40 @@ public void goo()
await VerifyItemIsAbsentAsync(markup, "value");
}
+ [WorkItem(54361, "https://github.com/dotnet/roslyn/issues/54361")]
+ [Fact, Trait(Traits.Feature, Traits.Features.Completion)]
+ public async Task ConditionalAccessNullableIsUnwrappedOnParameter()
+ {
+ var markup = @"
+class A
+{
+ void M(System.DateTime? dt)
+ {
+ dt?.$$
+ }
+}
+";
+ await VerifyItemExistsAsync(markup, "Day");
+ await VerifyItemIsAbsentAsync(markup, "Value");
+ }
+
+ [WorkItem(54361, "https://github.com/dotnet/roslyn/issues/54361")]
+ [Fact, Trait(Traits.Feature, Traits.Features.Completion)]
+ public async Task NullableIsNotUnwrappedOnParameter()
+ {
+ var markup = @"
+class A
+{
+ void M(System.DateTime? dt)
+ {
+ dt.$$
+ }
+}
+";
+ await VerifyItemExistsAsync(markup, "Value");
+ await VerifyItemIsAbsentAsync(markup, "Day");
+ }
+
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task CompletionAfterConditionalIndexing()
{
@@ -9576,6 +9610,7 @@ void goo()
{
await VerifyItemExistsAsync(markup, "Item" + i);
}
+
await VerifyItemExistsAsync(markup, "ToString");
await VerifyItemIsAbsentAsync(markup, "Item1");
@@ -11293,5 +11328,38 @@ int M()
}
}", "y");
}
+
+ [Fact, Trait(Traits.Feature, Traits.Features.KeywordRecommending)]
+ [WorkItem(53930, "https://github.com/dotnet/roslyn/issues/53930")]
+ public async Task TestTypeParameterConstraintedToInterfaceWithStatics()
+ {
+ var source = @"
+interface I1
+{
+ static void M0();
+ static abstract void M1();
+ abstract static int P1 { get; set; }
+ abstract static event System.Action E1;
+}
+
+interface I2
+{
+ static abstract void M2();
+}
+
+class Test
+{
+ void M(T x) where T : I1, I2
+ {
+ T.$$
+ }
+}
+";
+ await VerifyItemIsAbsentAsync(source, "M0");
+ await VerifyItemExistsAsync(source, "M1");
+ await VerifyItemExistsAsync(source, "M2");
+ await VerifyItemExistsAsync(source, "P1");
+ await VerifyItemExistsAsync(source, "E1");
+ }
}
}
diff --git a/src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs b/src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
index 2116a5ac38b23..16f228209a291 100644
--- a/src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
+++ b/src/EditorFeatures/CSharpTest/ConvertTupleToStruct/ConvertTupleToStructTests.cs
@@ -48,7 +48,9 @@ private static async Task TestAsync(
if (index != 0)
Assert.NotNull(equivalenceKey);
- var test = new VerifyCS.Test
+ options ??= new OptionsCollection(LanguageNames.CSharp);
+
+ await new VerifyCS.Test
{
TestCode = text,
FixedCode = expected,
@@ -57,11 +59,8 @@ private static async Task TestAsync(
CodeActionIndex = index,
CodeActionEquivalenceKey = equivalenceKey,
ExactActionSetOffered = actions,
- };
-
- if (options != null)
- test.Options.AddRange(options);
- await test.RunAsync();
+ Options = { options },
+ }.RunAsync();
}
#region update containing member tests
@@ -2278,7 +2277,8 @@ public static implicit operator NewStruct((int a, int a) value)
return new NewStruct(value.a, value.a);
}
}";
- var test = new VerifyCS.Test
+
+ await new VerifyCS.Test
{
TestCode = text,
FixedCode = expected,
@@ -2349,11 +2349,9 @@ public static implicit operator NewStruct((int a, int a) value)
// /0/Test0.cs(49,45): error CS0229: Ambiguity between '(int a, int a).a' and '(int a, int a).a'
DiagnosticResult.CompilerError("CS0229").WithSpan(49, 45, 49, 46).WithArguments("(int a, int a).a", "(int a, int a).a"),
}
- }
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ },
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Theory, CombinatorialData, Trait(Traits.Feature, Traits.Features.CodeActionsConvertTupleToStruct)]
@@ -3352,7 +3350,7 @@ void Goo()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestState =
{
@@ -3373,10 +3371,8 @@ void Goo()
CodeActionIndex = 1,
CodeActionEquivalenceKey = Scope.ContainingType.ToString(),
TestHost = host,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
#endregion update containing project tests
@@ -3511,7 +3507,7 @@ void Goo()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
CodeActionIndex = 2,
CodeActionEquivalenceKey = Scope.ContainingProject.ToString(),
@@ -3524,10 +3520,8 @@ void Goo()
{
Sources = { expected1, expected2 },
},
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
#endregion
@@ -3638,7 +3632,7 @@ void Goo()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
CodeActionIndex = 3,
CodeActionEquivalenceKey = Scope.DependentProjects.ToString(),
@@ -3667,10 +3661,8 @@ void Goo()
}
},
},
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Theory, CombinatorialData, Trait(Traits.Feature, Traits.Features.CodeActionsConvertTupleToStruct)]
@@ -3777,7 +3769,7 @@ void Goo()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
CodeActionIndex = 3,
CodeActionEquivalenceKey = Scope.DependentProjects.ToString(),
@@ -3798,10 +3790,8 @@ void Goo()
["DependencyProject"] = { Sources = { expected2 } }
},
},
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
#endregion
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/AddExplicitCast/AddExplicitCastTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/AddExplicitCast/AddExplicitCastTests.cs
index 76b210500ddf9..c959df4927171 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/AddExplicitCast/AddExplicitCastTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/AddExplicitCast/AddExplicitCastTests.cs
@@ -2522,6 +2522,7 @@ public Test(string s, Base b, int i, params object[] list) : this(d : [||]b, s :
var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters());
Assert.Equal(2, actions.Length);
}
+
var expect_0 =
@"
class Program
@@ -2671,6 +2672,7 @@ void M()
var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters());
Assert.Equal(2, actions.Length);
}
+
var expect_0 =
@"
class Program
@@ -2746,6 +2748,7 @@ void M()
var (actions, actionToInvoke) = await GetCodeActionsAsync(workspace, new TestParameters());
Assert.Equal(3, actions.Length);
}
+
var expect_0 =
@"
class Program
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/Suppression/SuppressionTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/Suppression/SuppressionTests.cs
index de59148fc6de0..0fc6908c7a5b2 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/Suppression/SuppressionTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/Suppression/SuppressionTests.cs
@@ -927,6 +927,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
}
+
break;
}
}
diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs
index 53caa05b1a1f1..ef4139fe6426c 100644
--- a/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs
+++ b/src/EditorFeatures/CSharpTest/Diagnostics/UpgradeProject/UpgradeProjectTests.cs
@@ -1001,7 +1001,7 @@ interface I2
static T1 M1([|T1|] x) => x;
}
",
- expected: LanguageVersion.Preview,
+ expected: LanguageVersion.CSharp9,
new CSharpParseOptions(LanguageVersion.CSharp8));
}
@@ -1011,13 +1011,13 @@ public async Task UpgradeProjectForSealedToStringInRecords_CS8912()
await TestLanguageVersionUpgradedAsync(
@"
-
+
Assembly2
record [|Derived|] : Base;
-
+
public record Base
{
@@ -1027,7 +1027,48 @@ public record Base
",
- expected: LanguageVersion.Preview,
+ expected: LanguageVersion.CSharp10,
+ new CSharpParseOptions(LanguageVersion.CSharp9));
+ }
+
+ [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 UpgradeProjectForImplicitImplementationOfNonPublicMemebers_CS8704()
+ {
+ await TestLanguageVersionUpgradedAsync(
+@"
+public interface I1
+{
+ protected void M01();
+}
+
+class C1 : [|I1|]
+{
+ public void M01() {}
+}
+",
+ expected: LanguageVersion.CSharp10,
new CSharpParseOptions(LanguageVersion.CSharp9));
}
}
diff --git a/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs b/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs
index 326a0fc2cdb94..80b636ce7a8ed 100644
--- a/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs
+++ b/src/EditorFeatures/CSharpTest/DocumentationComments/DocumentationCommentTests.cs
@@ -54,6 +54,22 @@ record R;";
VerifyTypingCharacter(code, expected);
}
+ [WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
+ public void TypingCharacter_RecordStruct()
+ {
+ var code =
+@"//$$
+record struct R;";
+
+ var expected =
+@"///
+/// $$
+///
+record struct R;";
+
+ VerifyTypingCharacter(code, expected);
+ }
+
[WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
public void TypingCharacter_RecordWithPositionalParameters()
{
@@ -72,6 +88,24 @@ record R(string S, int I);";
VerifyTypingCharacter(code, expected);
}
+ [WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
+ public void TypingCharacter_RecordStructWithPositionalParameters()
+ {
+ var code =
+@"//$$
+record struct R(string S, int I);";
+
+ var expected =
+@"///
+/// $$
+///
+///
+///
+record struct R(string S, int I);";
+
+ VerifyTypingCharacter(code, expected);
+ }
+
[WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
public void TypingCharacter_Class_NewLine()
{
@@ -1515,6 +1549,20 @@ record R;";
VerifyInsertCommentCommand(code, expected);
}
+ [WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
+ public void Command_RecordStruct()
+ {
+ var code = "record struct R$$;";
+
+ var expected =
+@"///
+/// $$
+///
+record struct R;";
+
+ VerifyInsertCommentCommand(code, expected);
+ }
+
[WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
public void Command_RecordWithPositionalParameters()
{
@@ -1531,6 +1579,22 @@ record R(string S, int I);";
VerifyInsertCommentCommand(code, expected);
}
+ [WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
+ public void Command_RecordStructWithPositionalParameters()
+ {
+ var code = "record struct R$$(string S, int I);";
+
+ var expected =
+@"///
+/// $$
+///
+///
+///
+record struct R(string S, int I);";
+
+ VerifyInsertCommentCommand(code, expected);
+ }
+
[WorkItem(4817, "https://github.com/dotnet/roslyn/issues/4817")]
[WpfFact, Trait(Traits.Feature, Traits.Features.DocumentationComments)]
public void Command_Class_AutoGenerateXmlDocCommentsOff()
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
index 4fa5b89fd2ade..a5306fe2a6398 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/ActiveStatementTests.cs
@@ -1867,7 +1867,7 @@ public C() {}
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1", FeaturesResources.const_field));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "a = 1", FeaturesResources.const_field));
}
[Fact]
@@ -1917,7 +1917,7 @@ public C() {}
var active = GetActiveStatements(src1, src2);
edits.VerifyRudeDiagnostics(active,
- Diagnostic(RudeEditKind.ModifiersUpdate, "const int a = 1, b = 2", FeaturesResources.const_field));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "a = 1", FeaturesResources.const_field));
}
[Fact]
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs
index 4b417edbe5a0a..9e69b9b3ad552 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/CSharpEditAndContinueTestHelpers.cs
@@ -11,6 +11,7 @@
using Microsoft.CodeAnalysis.EditAndContinue;
using Microsoft.CodeAnalysis.EditAndContinue.UnitTests;
using Microsoft.CodeAnalysis.Text;
+using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
index fd1d4962d4c04..794c9d3f61a9e 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/Helpers/EditingTestBase.cs
@@ -15,6 +15,7 @@
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Debugger.Contracts.EditAndContinue;
+using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.EditAndContinue.UnitTests
@@ -34,6 +35,17 @@ internal enum MethodKind
ConstructorWithParameters
}
+ public static string GetResource(string keyword)
+ => keyword switch
+ {
+ "class" => FeaturesResources.class_,
+ "struct" => CSharpFeaturesResources.struct_,
+ "interface" => FeaturesResources.interface_,
+ "record" => CSharpFeaturesResources.record_,
+ "record struct" => CSharpFeaturesResources.record_struct,
+ _ => throw ExceptionUtilities.UnexpectedValue(keyword)
+ };
+
internal static SemanticEditDescription[] NoSemanticEdits = Array.Empty();
internal static RudeEditDiagnosticDescription Diagnostic(RudeEditKind rudeEditKind, string squiggle, params string[] arguments)
diff --git a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
index 095a59d3feecc..3827ac1e2d9b2 100644
--- a/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditAndContinue/TopLevelEditingTests.cs
@@ -428,7 +428,7 @@ public void ExternAliasDelete()
#endregion
- #region Attributes
+ #region Assembly/Module Attributes
[Fact]
public void Insert_TopLevelAttribute()
@@ -492,243 +492,157 @@ public void Reorder_TopLevelAttribute()
edits.VerifyRudeDiagnostics();
}
- [Fact]
- public void UpdateAttributes1()
- {
- var attribute = "public class A1Attribute : System.Attribute { }\n\n" +
- "public class A2Attribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[A1]class C { }";
- var src2 = attribute + "[A2]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[A1]class C { }]@98 -> [[A2]class C { }]@98");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
- }
-
- [Fact]
- public void UpdateAttributes2()
- {
- var src1 = "[System.Obsolete(\"1\")]class C { }";
- var src2 = "[System.Obsolete(\"2\")]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[System.Obsolete(\"1\")]class C { }]@0 -> [[System.Obsolete(\"2\")]class C { }]@0");
+ #endregion
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
- }
+ #region Types
- [Fact]
- public void DeleteAttributes()
+ [Theory]
+ [InlineData("class", "struct")]
+ [InlineData("class", "record")] // TODO: Allow this conversion: https://github.com/dotnet/roslyn/issues/51874
+ [InlineData("class", "record struct")]
+ [InlineData("struct", "record struct")] // TODO: Allow this conversion: https://github.com/dotnet/roslyn/issues/51874
+ public void Type_Kind_Update(string oldKeyword, string newKeyword)
{
- var attribute = "public class AAttribute : System.Attribute { }\n\n" +
- "public class BAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[A, B]class C { }";
- var src2 = attribute + "[A]class C { }";
+ var src1 = oldKeyword + " C { }";
+ var src2 = newKeyword + " C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [[A, B]class C { }]@96 -> [[A]class C { }]@96");
+ "Update [" + oldKeyword + " C { }]@0 -> [" + newKeyword + " C { }]@0");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ Diagnostic(RudeEditKind.TypeKindUpdate, newKeyword + " C"));
}
[Fact]
- public void DeleteAttributes2()
+ public void Type_Modifiers_Static_Remove()
{
- var attribute = "public class AAttribute : System.Attribute { }\n\n" +
- "public class BAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[B, A]class C { }";
- var src2 = attribute + "[A]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[B, A]class C { }]@96 -> [[A]class C { }]@96");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
- }
-
- [Fact]
- public void InsertAttributes_SupportedByRuntime()
- {
- var attribute = "public class AAttribute : System.Attribute { }\n\n" +
- "public class BAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[A]class C { }";
- var src2 = attribute + "[A, B]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[A]class C { }]@96 -> [[A, B]class C { }]@96");
-
- edits.VerifySemantics(
- ActiveStatementsDescription.Empty,
- new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")) },
- capabilities: EditAndContinueTestHelpers.Net5RuntimeCapabilities | EditAndContinueCapabilities.ChangeCustomAttributes);
- }
-
- [Fact]
- public void InsertAttributes1()
- {
- var attribute = "public class AAttribute : System.Attribute { }\n\n" +
- "public class BAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[A]class C { }";
- var src2 = attribute + "[A, B]class C { }";
+ var src1 = "public static class C { }";
+ var src2 = "public class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [[A]class C { }]@96 -> [[A, B]class C { }]@96");
+ "Update [public static class C { }]@0 -> [public class C { }]@0");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public class C", FeaturesResources.class_));
}
- [Fact]
- public void InsertAttributes2()
+ [Theory]
+ [InlineData("public")]
+ [InlineData("protected")]
+ [InlineData("private")]
+ [InlineData("private protected")]
+ [InlineData("internal protected")]
+ public void Type_Modifiers_Accessibility_Change(string accessibility)
{
- var attribute = "public class AAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "class C { }";
- var src2 = attribute + "[A]class C { }";
+ var src1 = accessibility + " class C { }";
+ var src2 = "class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [class C { }]@48 -> [[A]class C { }]@48");
+ "Update [" + accessibility + " class C { }]@0 -> [class C { }]@0");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
- }
-
- [Fact]
- public void ReorderAttributes1()
- {
- var src1 = "[A(1), B(2), C(3)]class C { }";
- var src2 = "[C(3), A(1), B(2)]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[A(1), B(2), C(3)]class C { }]@0 -> [[C(3), A(1), B(2)]class C { }]@0");
-
- edits.VerifyRudeDiagnostics();
+ Diagnostic(RudeEditKind.ChangingAccessibility, "class C", FeaturesResources.class_));
}
- [Fact]
- public void ReorderAttributes2()
- {
- var src1 = "[A, B, C]class C { }";
- var src2 = "[B, C, A]class C { }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[A, B, C]class C { }]@0 -> [[B, C, A]class C { }]@0");
+ [Theory]
+ [InlineData("public", "public")]
+ [InlineData("internal", "internal")]
+ [InlineData("", "internal")]
+ [InlineData("internal", "")]
+ [InlineData("protected", "protected")]
+ [InlineData("private", "private")]
+ [InlineData("private protected", "private protected")]
+ [InlineData("internal protected", "internal protected")]
+ public void Type_Modifiers_Accessibility_Partial(string accessibilityA, string accessibilityB)
+ {
+ var srcA1 = accessibilityA + " partial class C { }";
+ var srcB1 = "partial class C { }";
+ var srcA2 = "partial class C { }";
+ var srcB2 = accessibilityB + " partial class C { }";
- edits.VerifyRudeDiagnostics();
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(),
+ DocumentResults(),
+ });
}
[Fact]
- public void ReorderAndUpdateAttributes()
+ public void Type_Modifiers_Internal_Remove()
{
- var attribute = "public class AAttribute : System.Attribute { }\n\n" +
- "public class BAttribute : System.Attribute { }\n\n";
-
- var src1 = attribute + "[System.Obsolete(\"1\"), A, B]class C { }";
- var src2 = attribute + "[A, B, System.Obsolete(\"2\")]class C { }";
+ var src1 = "internal interface C { }";
+ var src2 = "interface C { }";
var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [[System.Obsolete(\"1\"), A, B]class C { }]@96 -> [[A, B, System.Obsolete(\"2\")]class C { }]@96");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ edits.VerifySemantics();
}
- #endregion
-
- #region Classes, Structs, Interfaces
-
[Fact]
- public void TypeKindUpdate()
+ public void Type_Modifiers_Internal_Add()
{
- var src1 = "class C { }";
- var src2 = "struct C { }";
+ var src1 = "struct C { }";
+ var src2 = "internal struct C { }";
var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [class C { }]@0 -> [struct C { }]@0");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.TypeKindUpdate, "struct C", CSharpFeaturesResources.struct_));
+ edits.VerifySemantics();
}
- [Fact]
- public void TypeKindUpdate2()
+ [Theory]
+ [InlineData("class")]
+ [InlineData("struct")]
+ [InlineData("interface")]
+ [InlineData("record")]
+ [InlineData("record struct")]
+ public void Type_Modifiers_NestedPrivateInInterface_Remove(string keyword)
{
- // TODO: Allow this conversion: https://github.com/dotnet/roslyn/issues/51874
- var src1 = "class C { }";
- var src2 = "record C { }";
+ var src1 = "interface C { private " + keyword + " S { } }";
+ var src2 = "interface C { " + keyword + " S { } }";
var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [class C { }]@0 -> [record C { }]@0");
-
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.TypeKindUpdate, "record C", CSharpFeaturesResources.record_));
+ Diagnostic(RudeEditKind.ChangingAccessibility, keyword + " S", GetResource(keyword)));
}
- [Fact]
- public void TypeKindUpdate3()
+ [Theory]
+ [InlineData("class")]
+ [InlineData("struct")]
+ [InlineData("interface")]
+ [InlineData("record")]
+ [InlineData("record struct")]
+ public void Type_Modifiers_NestedPrivateInClass_Add(string keyword)
{
- var src1 = "record C { }";
- var src2 = "record struct C { }";
+ var src1 = "class C { " + keyword + " S { } }";
+ var src2 = "class C { private " + keyword + " S { } }";
var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [record C { }]@0 -> [record struct C { }]@0");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.TypeKindUpdate, "record struct C", CSharpFeaturesResources.record_struct));
+ edits.VerifySemantics();
}
- [Fact]
- public void Class_Modifiers_Update()
+ [Theory]
+ [InlineData("class")]
+ [InlineData("struct")]
+ [InlineData("interface")]
+ [InlineData("record")]
+ [InlineData("record struct")]
+ public void Type_Modifiers_NestedPublicInInterface_Add(string keyword)
{
- var src1 = "public static class C { }";
- var src2 = "public class C { }";
+ var src1 = "interface C { " + keyword + " S { } }";
+ var src2 = "interface C { public " + keyword + " S { } }";
var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Update [public static class C { }]@0 -> [public class C { }]@0");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "public class C", FeaturesResources.class_));
+ edits.VerifySemantics();
}
[Fact, WorkItem(48628, "https://github.com/dotnet/roslyn/issues/48628")]
- public void Class_ModifiersUpdate_IgnoreUnsafe()
+ public void Type_Modifiers_Unsafe_Add()
{
var src1 = "public class C { }";
var src2 = "public unsafe class C { }";
@@ -742,7 +656,7 @@ public void Class_ModifiersUpdate_IgnoreUnsafe()
}
[Fact, WorkItem(48628, "https://github.com/dotnet/roslyn/issues/48628")]
- public void ModifiersUpdate_IgnoreUnsafe()
+ public void Type_Modifiers_Unsafe_Remove()
{
var src1 = @"
using System;
@@ -789,7 +703,7 @@ public event Action A { add { } remove { } }
}
[Fact, WorkItem(48628, "https://github.com/dotnet/roslyn/issues/48628")]
- public void ModifiersUpdate_IgnoreUnsafe2()
+ public void Type_Modifiers_Unsafe_DeleteInsert()
{
var srcA1 = "partial class C { unsafe void F() { } }";
var srcB1 = "partial class C { }";
@@ -809,7 +723,7 @@ public void ModifiersUpdate_IgnoreUnsafe2()
}
[Fact]
- public void Struct_Modifiers_Ref_Update1()
+ public void Type_Modifiers_Ref_Add()
{
var src1 = "public struct C { }";
var src2 = "public ref struct C { }";
@@ -824,7 +738,7 @@ public void Struct_Modifiers_Ref_Update1()
}
[Fact]
- public void Struct_Modifiers_Ref_Update2()
+ public void Type_Modifiers_Ref_Remove()
{
var src1 = "public ref struct C { }";
var src2 = "public struct C { }";
@@ -839,7 +753,7 @@ public void Struct_Modifiers_Ref_Update2()
}
[Fact]
- public void Struct_Modifiers_Readonly_Update1()
+ public void Type_Modifiers_ReadOnly_Add()
{
var src1 = "public struct C { }";
var src2 = "public readonly struct C { }";
@@ -854,7 +768,7 @@ public void Struct_Modifiers_Readonly_Update1()
}
[Fact]
- public void Struct_Modifiers_Readonly_Update2()
+ public void Type_Modifiers_ReadOnly_Remove()
{
var src1 = "public readonly struct C { }";
var src2 = "public struct C { }";
@@ -869,49 +783,175 @@ public void Struct_Modifiers_Readonly_Update2()
}
[Fact]
- public void Interface_Modifiers_Update()
+ public void Type_Attribute_Update_NotSupportedByRuntime1()
{
- var src1 = "public interface C { }";
- var src2 = "interface C { }";
+ var attribute = "public class A1Attribute : System.Attribute { }\n\n" +
+ "public class A2Attribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[A1]class C { }";
+ var src2 = attribute + "[A2]class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [public interface C { }]@0 -> [interface C { }]@0");
+ "Update [[A1]class C { }]@98 -> [[A2]class C { }]@98");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "interface C", FeaturesResources.interface_));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
}
[Fact]
- public void Struct_Modifiers_Update()
+ public void Type_Attribute_Update_NotSupportedByRuntime2()
{
- var src1 = "struct C { }";
- var src2 = "public struct C { }";
+ var src1 = "[System.Obsolete(\"1\")]class C { }";
+ var src2 = "[System.Obsolete(\"2\")]class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [struct C { }]@0 -> [public struct C { }]@0");
+ "Update [[System.Obsolete(\"1\")]class C { }]@0 -> [[System.Obsolete(\"2\")]class C { }]@0");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "public struct C", CSharpFeaturesResources.struct_));
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
}
[Fact]
- public void Struct_UnsafeModifier_Update()
+ public void Type_Attribute_Delete_NotSupportedByRuntime1()
{
- var src1 = "unsafe struct C { }";
- var src2 = "struct C { }";
+ var attribute = "public class AAttribute : System.Attribute { }\n\n" +
+ "public class BAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[A, B]class C { }";
+ var src2 = attribute + "[A]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[A, B]class C { }]@96 -> [[A]class C { }]@96");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ }
+
+ [Fact]
+ public void Type_Attribute_Delete_NotSupportedByRuntime2()
+ {
+ var attribute = "public class AAttribute : System.Attribute { }\n\n" +
+ "public class BAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[B, A]class C { }";
+ var src2 = attribute + "[A]class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifyEdits(
- "Update [unsafe struct C { }]@0 -> [struct C { }]@0");
+ "Update [[B, A]class C { }]@96 -> [[A]class C { }]@96");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ }
+
+ [Fact]
+ public void Type_Attribute_Add()
+ {
+ var attribute = "public class AAttribute : System.Attribute { }\n\n" +
+ "public class BAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[A]class C { }";
+ var src2 = attribute + "[A, B]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[A]class C { }]@96 -> [[A, B]class C { }]@96");
+
+ edits.VerifySemantics(
+ ActiveStatementsDescription.Empty,
+ new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C")) },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ }
+
+ [Fact]
+ public void Type_Attribute_Add_NotSupportedByRuntime1()
+ {
+ var attribute = "public class AAttribute : System.Attribute { }\n\n" +
+ "public class BAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[A]class C { }";
+ var src2 = attribute + "[A, B]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[A]class C { }]@96 -> [[A, B]class C { }]@96");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ }
+
+ [Fact]
+ public void Type_Attribute_Add_NotSupportedByRuntime2()
+ {
+ var attribute = "public class AAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "class C { }";
+ var src2 = attribute + "[A]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [class C { }]@48 -> [[A]class C { }]@48");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ }
+
+ [Fact]
+ public void Type_Attribute_Reorder1()
+ {
+ var src1 = "[A(1), B(2), C(3)]class C { }";
+ var src2 = "[C(3), A(1), B(2)]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[A(1), B(2), C(3)]class C { }]@0 -> [[C(3), A(1), B(2)]class C { }]@0");
edits.VerifyRudeDiagnostics();
}
+ [Fact]
+ public void Type_Attribute_Reorder2()
+ {
+ var src1 = "[A, B, C]class C { }";
+ var src2 = "[B, C, A]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[A, B, C]class C { }]@0 -> [[B, C, A]class C { }]@0");
+
+ edits.VerifyRudeDiagnostics();
+ }
+
+ [Fact]
+ public void Type_Attribute_ReorderAndUpdate_NotSupportedByRuntime()
+ {
+ var attribute = "public class AAttribute : System.Attribute { }\n\n" +
+ "public class BAttribute : System.Attribute { }\n\n";
+
+ var src1 = attribute + "[System.Obsolete(\"1\"), A, B]class C { }";
+ var src2 = attribute + "[A, B, System.Obsolete(\"2\")]class C { }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [[System.Obsolete(\"1\"), A, B]class C { }]@96 -> [[A, B, System.Obsolete(\"2\")]class C { }]@96");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "class C", FeaturesResources.class_));
+ }
+
[Fact]
public void Class_Name_Update1()
{
@@ -1220,7 +1260,7 @@ public void RefStructInsert()
}
[Fact]
- public void ReadOnlyStructInsert()
+ public void Struct_ReadOnly_Insert()
{
var src1 = "";
var src2 = "readonly struct X { }";
@@ -1234,7 +1274,7 @@ public void ReadOnlyStructInsert()
}
[Fact]
- public void RefStructUpdate()
+ public void Struct_RefModifier_Add()
{
var src1 = "struct X { }";
var src2 = "ref struct X { }";
@@ -1249,7 +1289,7 @@ public void RefStructUpdate()
}
[Fact]
- public void ReadOnlyStructUpdate()
+ public void Struct_ReadonlyModifier_Add()
{
var src1 = "struct X { }";
var src2 = "readonly struct X { }";
@@ -1263,6 +1303,25 @@ public void ReadOnlyStructUpdate()
Diagnostic(RudeEditKind.ModifiersUpdate, "readonly struct X", SyntaxFacts.GetText(SyntaxKind.StructKeyword)));
}
+ [Theory]
+ [InlineData("ref")]
+ [InlineData("readonly")]
+ public void Struct_Modifiers_Partial_InsertDelete(string modifier)
+ {
+ var srcA1 = modifier + " partial struct S { }";
+ var srcB1 = "partial struct S { }";
+ var srcA2 = "partial struct S { }";
+ var srcB2 = modifier + " partial struct S { }";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(),
+ DocumentResults()
+ });
+ }
+
[Fact]
public void Class_ImplementingInterface_Add()
{
@@ -1626,7 +1685,7 @@ interface I { void F() {} }
}
[Fact]
- public void Type_DeleteInsert_NonInsertableMembers()
+ public void Type_NonInsertableMembers_DeleteInsert()
{
var srcA1 = @"
abstract class C
@@ -1648,6 +1707,7 @@ void F() {}
var srcA2 = srcB1;
var srcB2 = srcA1;
+ // TODO: The methods without bodies do not need to be updated.
EditAndContinueValidation.VerifySemantics(
new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
@@ -1657,14 +1717,72 @@ void F() {}
DocumentResults(
semanticEdits: new[]
{
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("AbstractMethod")),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("VirtualMethod")),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("ToString")),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("I.G")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("I").GetMember("G")),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("I").GetMember("F")),
})
});
}
+ [Fact]
+ public void Type_Attribute_NonInsertableMembers_DeleteInsert()
+ {
+ var srcA1 = @"
+abstract class C
+{
+ public abstract void AbstractMethod();
+ public virtual void VirtualMethod() {}
+ public override string ToString() => null;
+ public void I.G() {}
+}
+
+interface I
+{
+ void G();
+ void F() {}
+}
+";
+ var srcB1 = "";
+
+ var srcA2 = "";
+ var srcB2 = @"
+abstract class C
+{
+ [System.Obsolete]public abstract void AbstractMethod();
+ public virtual void VirtualMethod() {}
+ public override string ToString() => null;
+ public void I.G() {}
+}
+
+interface I
+{
+ [System.Obsolete]void G();
+ void F() {}
+}";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(),
+
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("AbstractMethod")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("VirtualMethod")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("ToString")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("I.G")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("I").GetMember("G")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("I").GetMember("F")),
+ })
+ },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ }
+
[Fact]
public void Type_DeleteInsert_DataMembers()
{
@@ -1698,6 +1816,8 @@ class C
DocumentResults(
semanticEdits: new[]
{
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").SetMethod),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true),
})
});
@@ -1738,6 +1858,8 @@ partial class C
DocumentResults(
semanticEdits: new[]
{
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").SetMethod),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true),
})
});
@@ -1778,6 +1900,8 @@ class C
DocumentResults(
semanticEdits: new[]
{
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.P").SetMethod),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true),
}),
@@ -2001,7 +2125,7 @@ public void Record_ImplementSynthesized_PrintMembers()
var src2 = @"
record C
{
- protected bool PrintMembers(System.Text.StringBuilder builder)
+ protected virtual bool PrintMembers(System.Text.StringBuilder builder)
{
return true;
}
@@ -2715,24 +2839,36 @@ public int X
[Fact]
public void Record_MoveProperty_Partial()
{
- var srcA1 = @"partial record C(int X)
+ var srcA1 = @"
+partial record C(int X)
{
public int Y { get; init; }
}";
- var srcB1 = @"partial record C;";
- var srcA2 = @"partial record C(int X);";
- var srcB2 = @"partial record C
+ var srcB1 = @"
+partial record C;
+";
+
+ var srcA2 = @"
+partial record C(int X);
+";
+
+ var srcB2 = @"
+partial record C
{
public int Y { get; init; }
}";
EditAndContinueValidation.VerifySemantics(
- new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
{
DocumentResults(),
-
- DocumentResults(),
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Y").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.Y").SetMethod)
+ }),
});
}
@@ -2976,7 +3112,7 @@ public void EnumBaseTypeDelete()
}
[Fact]
- public void EnumModifierUpdate()
+ public void EnumAccessibilityChange()
{
var src1 = "public enum Color { Red = 1, Blue = 2, }";
var src2 = "enum Color { Red = 1, Blue = 2, }";
@@ -2986,8 +3122,18 @@ public void EnumModifierUpdate()
edits.VerifyEdits(
"Update [public enum Color { Red = 1, Blue = 2, }]@0 -> [enum Color { Red = 1, Blue = 2, }]@0");
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "enum Color", FeaturesResources.enum_));
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAccessibility, "enum Color", FeaturesResources.enum_));
+ }
+
+ [Fact]
+ public void EnumAccessibilityNoChange()
+ {
+ var src1 = "internal enum Color { Red = 1, Blue = 2, }";
+ var src2 = "enum Color { Red = 1, Blue = 2, }";
+
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifySemantics();
}
[Fact]
@@ -3318,7 +3464,7 @@ public void Delegates_Rename()
}
[Fact]
- public void Delegates_Update_Modifiers()
+ public void Delegates_Accessibility_Update()
{
var src1 = "public delegate void D();";
var src2 = "private delegate void D();";
@@ -3329,7 +3475,7 @@ public void Delegates_Update_Modifiers()
"Update [public delegate void D();]@0 -> [private delegate void D();]@0");
edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "private delegate void D()", FeaturesResources.delegate_));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "private delegate void D()", FeaturesResources.delegate_));
}
[Fact]
@@ -4535,101 +4681,6 @@ public void NamespaceReorder2()
#region Members
- [Fact]
- public void MemberUpdate_Modifier_ReadOnly_Remove()
- {
- var src1 = @"
-using System;
-
-struct S
-{
- // methods
- public readonly int M() => 1;
-
- // properties
- public readonly int P => 1;
- public readonly int Q { get; }
- public int R { readonly get; readonly set; }
-
- // events
- public readonly event Action E { add {} remove {} }
- public event Action F { readonly add {} readonly remove {} }
-}";
- var src2 = @"
-using System;
-struct S
-{
- // methods
- public int M() => 1;
-
- // properties
- public int P => 1;
- public int Q { get; }
- public int R { get; set; }
-
- // events
- public event Action E { add {} remove {} }
- public event Action F { add {} remove {} }
-}";
- var edits = GetTopEdits(src1, src2);
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "public int M()", FeaturesResources.method),
- Diagnostic(RudeEditKind.ModifiersUpdate, "public int P", FeaturesResources.property_),
- Diagnostic(RudeEditKind.ModifiersUpdate, "public int Q", FeaturesResources.auto_property),
- Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.property_getter),
- Diagnostic(RudeEditKind.ModifiersUpdate, "set", CSharpFeaturesResources.property_setter),
- Diagnostic(RudeEditKind.ModifiersUpdate, "add", FeaturesResources.event_accessor),
- Diagnostic(RudeEditKind.ModifiersUpdate, "remove", FeaturesResources.event_accessor));
- }
-
- [Fact]
- public void MemberUpdate_Modifier_ReadOnly_Add()
- {
- var src1 = @"
-using System;
-
-struct S
-{
- // methods
- public int M() => 1;
-
- // properties
- public int P => 1;
- public int Q { get; }
- public int R { get; set; }
-
- // events
- public event Action E { add {} remove {} }
- public event Action F { add {} remove {} }
-}";
- var src2 = @"
-using System;
-
-struct S
-{
- // methods
- public readonly int M() => 1;
-
- // properties
- public readonly int P => 1;
- public readonly int Q { get; }
- public int R { readonly get; readonly set; }
-
- // events
- public readonly event Action E { add {} remove {} }
- public event Action F { readonly add {} readonly remove {} }
-}";
- var edits = GetTopEdits(src1, src2);
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly int M()", FeaturesResources.method),
- Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly int P", FeaturesResources.property_),
- Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly int Q", FeaturesResources.auto_property),
- Diagnostic(RudeEditKind.ModifiersUpdate, "readonly get", CSharpFeaturesResources.property_getter),
- Diagnostic(RudeEditKind.ModifiersUpdate, "readonly set", CSharpFeaturesResources.property_setter),
- Diagnostic(RudeEditKind.ModifiersUpdate, "readonly add", FeaturesResources.event_accessor),
- Diagnostic(RudeEditKind.ModifiersUpdate, "readonly remove", FeaturesResources.event_accessor));
- }
-
[Fact]
public void PartialMember_DeleteInsert_SingleDocument()
{
@@ -4753,6 +4804,8 @@ event Action E { add {} remove {} }
semanticEdits: new[]
{
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("M"), preserveLocalVariables: false),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P1").GetMethod, preserveLocalVariables: false),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P1").SetMethod, preserveLocalVariables: false),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P2").GetMethod, preserveLocalVariables: false),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P2").SetMethod, preserveLocalVariables: false),
SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMembers("this[]").Cast().Single(m => m.GetParameters().Single().Type.Name == "Int32").GetMethod, preserveLocalVariables: false),
@@ -5086,6 +5139,200 @@ public void PartialMember_DeleteInsert_ConstructorWithInitializers()
#region Methods
+ [Theory]
+ [InlineData("static")]
+ [InlineData("virtual")]
+ [InlineData("abstract")]
+ [InlineData("override")]
+ [InlineData("sealed override", "override")]
+ public void Method_Modifiers_Update(string oldModifiers, string newModifiers = "")
+ {
+ if (oldModifiers != "")
+ {
+ oldModifiers += " ";
+ }
+
+ if (newModifiers != "")
+ {
+ newModifiers += " ";
+ }
+
+ var src1 = "class C { " + oldModifiers + "int F() => 0; }";
+ var src2 = "class C { " + newModifiers + "int F() => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [" + oldModifiers + "int F() => 0;]@10 -> [" + newModifiers + "int F() => 0;]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int F()", FeaturesResources.method));
+ }
+
+ [Fact]
+ public void Method_NewModifier_Add()
+ {
+ var src1 = "class C { int F() => 0; }";
+ var src2 = "class C { new int F() => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [int F() => 0;]@10 -> [new int F() => 0;]@10");
+
+ // Currently, an edit is produced eventhough there is no metadata/IL change. Consider improving.
+ edits.VerifySemantics(
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("F")));
+ }
+
+ [Fact]
+ public void Method_NewModifier_Remove()
+ {
+ var src1 = "class C { new int F() => 0; }";
+ var src2 = "class C { int F() => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [new int F() => 0;]@10 -> [int F() => 0;]@10");
+
+ // Currently, an edit is produced eventhough there is no metadata/IL change. Consider improving.
+ edits.VerifySemantics(
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("F")));
+ }
+
+ [Fact]
+ public void Method_ReadOnlyModifier_Add_InMutableStruct()
+ {
+ var src1 = @"
+struct S
+{
+ public int M() => 1;
+}";
+ var src2 = @"
+struct S
+{
+ public readonly int M() => 1;
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly int M()", FeaturesResources.method));
+ }
+
+ [Fact]
+ public void Method_ReadOnlyModifier_Add_InReadOnlyStruct1()
+ {
+ var src1 = @"
+readonly struct S
+{
+ public int M()
+ => 1;
+}";
+ var src2 = @"
+readonly struct S
+{
+ public readonly int M()
+ => 1;
+}";
+
+ var edits = GetTopEdits(src1, src2);
+
+ // Currently, an edit is produced eventhough the body nor IsReadOnly attribute have changed. Consider improving.
+ edits.VerifySemantics(
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMember("M")));
+ }
+
+ [Fact]
+ public void Method_ReadOnlyModifier_Add_InReadOnlyStruct2()
+ {
+ var src1 = @"
+readonly struct S
+{
+ public int M() => 1;
+}";
+ var src2 = @"
+struct S
+{
+ public readonly int M() => 1;
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "struct S", "struct"));
+ }
+
+ [Fact]
+ public void Method_AsyncModifier_Remove()
+ {
+ var src1 = @"
+class Test
+{
+ public async Task WaitAsync()
+ {
+ return 1;
+ }
+}";
+ var src2 = @"
+class Test
+{
+ public Task WaitAsync()
+ {
+ return Task.FromResult(1);
+ }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "public Task WaitAsync()", FeaturesResources.method));
+ }
+
+ [Fact]
+ public void Method_AsyncModifier_Add()
+ {
+ var src1 = @"
+class Test
+{
+ public Task WaitAsync()
+ {
+ return 1;
+ }
+}";
+ var src2 = @"
+class Test
+{
+ public async Task WaitAsync()
+ {
+ await Task.Delay(1000);
+ return 1;
+ }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics();
+
+ VerifyPreserveLocalVariables(edits, preserveLocalVariables: false);
+ }
+
+ [Fact]
+ public void Method_AsyncModifier_Add_NotSupported()
+ {
+ var src1 = @"
+class Test
+{
+ public Task WaitAsync()
+ {
+ return 1;
+ }
+}";
+ var src2 = @"
+class Test
+{
+ public async Task WaitAsync()
+ {
+ await Task.Delay(1000);
+ return 1;
+ }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ capabilities: EditAndContinueTestHelpers.BaselineCapabilities,
+ Diagnostic(RudeEditKind.MakeMethodAsync, "public async Task WaitAsync()"));
+ }
+
[Fact]
public void Method_Update()
{
@@ -5581,11 +5828,56 @@ public void ExternMethodInsert()
var src1 = @"
using System;
using System.Runtime.InteropServices;
-
-class C
-{
-}";
- var src2 = @"
+
+class C
+{
+}";
+ var src2 = @"
+using System;
+using System.Runtime.InteropServices;
+
+class C
+{
+ [DllImport(""msvcrt.dll"")]
+ private static extern int puts(string c);
+}
+";
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ @"Insert [[DllImport(""msvcrt.dll"")]
+ private static extern int puts(string c);]@74",
+ "Insert [(string c)]@135",
+ "Insert [string c]@136");
+
+ // CLR doesn't support methods without a body
+ edits.VerifySemanticDiagnostics(
+ Diagnostic(RudeEditKind.InsertExtern, "private static extern int puts(string c)", FeaturesResources.method));
+ }
+
+ [Fact]
+ [WorkItem(755784, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755784"), WorkItem(835827, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835827")]
+ public void ExternMethodDeleteInsert()
+ {
+ var srcA1 = @"
+using System;
+using System.Runtime.InteropServices;
+
+class C
+{
+ [DllImport(""msvcrt.dll"")]
+ private static extern int puts(string c);
+}";
+ var srcA2 = @"
+using System;
+using System.Runtime.InteropServices;
+";
+
+ var srcB1 = @"
+using System;
+using System.Runtime.InteropServices;
+";
+ var srcB2 = @"
using System;
using System.Runtime.InteropServices;
@@ -5595,22 +5887,22 @@ class C
private static extern int puts(string c);
}
";
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- @"Insert [[DllImport(""msvcrt.dll"")]
- private static extern int puts(string c);]@74",
- "Insert [(string c)]@135",
- "Insert [string c]@136");
-
- // CLR doesn't support methods without a body
- edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.InsertExtern, "private static extern int puts(string c)", FeaturesResources.method));
+ // TODO: The method does not need to be updated since there are no sequence points generated for it.
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(),
+ DocumentResults(semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.puts")),
+ })
+ });
}
- [WorkItem(755784, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755784"), WorkItem(835827, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835827")]
[Fact]
- public void ExternMethodDeleteInsert()
+ [WorkItem(755784, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/755784"), WorkItem(835827, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/835827")]
+ public void ExternMethod_Attribute_DeleteInsert()
{
var srcA1 = @"
using System;
@@ -5637,6 +5929,7 @@ class C
class C
{
[DllImport(""msvcrt.dll"")]
+ [Obsolete]
private static extern int puts(string c);
}
";
@@ -5645,8 +5938,12 @@ class C
new[]
{
DocumentResults(),
- DocumentResults()
- });
+ DocumentResults(semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.puts")),
+ })
+ },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
}
[Fact]
@@ -5872,82 +6169,6 @@ static void Main() { }
Diagnostic(RudeEditKind.Delete, "static void Main()", FeaturesResources.parameter));
}
- [Fact]
- public void MethodUpdate_Modifier_Async_Remove()
- {
- var src1 = @"
-class Test
-{
- public async Task WaitAsync()
- {
- return 1;
- }
-}";
- var src2 = @"
-class Test
-{
- public Task WaitAsync()
- {
- return Task.FromResult(1);
- }
-}";
- var edits = GetTopEdits(src1, src2);
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingFromAsynchronousToSynchronous, "public Task WaitAsync()", FeaturesResources.method));
- }
-
- [Fact]
- public void MethodUpdate_Modifier_Async_Add()
- {
- var src1 = @"
-class Test
-{
- public Task WaitAsync()
- {
- return 1;
- }
-}";
- var src2 = @"
-class Test
-{
- public async Task WaitAsync()
- {
- await Task.Delay(1000);
- return 1;
- }
-}";
- var edits = GetTopEdits(src1, src2);
- edits.VerifyRudeDiagnostics();
-
- VerifyPreserveLocalVariables(edits, preserveLocalVariables: false);
- }
-
- [Fact]
- public void MethodUpdate_Modifier_Async_Add_NotSupported()
- {
- var src1 = @"
-class Test
-{
- public Task WaitAsync()
- {
- return 1;
- }
-}";
- var src2 = @"
-class Test
-{
- public async Task WaitAsync()
- {
- await Task.Delay(1000);
- return 1;
- }
-}";
- var edits = GetTopEdits(src1, src2);
- edits.VerifyRudeDiagnostics(
- capabilities: EditAndContinueTestHelpers.BaselineCapabilities,
- Diagnostic(RudeEditKind.MakeMethodAsync, "public async Task WaitAsync()"));
- }
-
[Fact]
public void MethodUpdate_AsyncMethod0()
{
@@ -7221,6 +7442,34 @@ public void PartialMethod_Insert()
#region Operators
+ [Theory]
+ [InlineData("implicit", "explicit")]
+ [InlineData("explicit", "implicit")]
+ public void Operator_Modifiers_Update(string oldModifiers, string newModifiers)
+ {
+ var src1 = "class C { public static " + oldModifiers + " operator int (C c) => 0; }";
+ var src2 = "class C { public static " + newModifiers + " operator int (C c) => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [public static " + oldModifiers + " operator int (C c) => 0;]@10 -> [public static " + newModifiers + " operator int (C c) => 0;]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public static " + newModifiers + " operator int (C c)", CSharpFeaturesResources.conversion_operator));
+ }
+
+ [Fact]
+ public void Operator_Conversion_ExternModifiers_Add()
+ {
+ var src1 = "class C { public static implicit operator bool (C c) => default; }";
+ var src2 = "class C { extern public static implicit operator bool (C c); }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.MethodBodyDelete, "extern public static implicit operator bool (C c)", CSharpFeaturesResources.conversion_operator));
+ }
+
[Fact]
public void OperatorInsert()
{
@@ -7494,6 +7743,23 @@ public void Operator_ReadOnlyRef_Parameter_Update()
#region Constructor, Destructor
+ [Fact]
+ [WorkItem(2068, "https://github.com/dotnet/roslyn/issues/2068")]
+ public void Constructor_ExternModifier_Add()
+ {
+ var src1 = "class C { }";
+ var src2 = "class C { public extern C(); }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Insert [public extern C();]@10",
+ "Insert [()]@25");
+
+ // The compiler generates an empty constructor.
+ edits.VerifySemanticDiagnostics();
+ }
+
[Fact]
public void ConstructorInitializer_Update1()
{
@@ -7634,7 +7900,7 @@ public void DestructorDelete_InsertConstructor()
"Delete [~B() { }]@10");
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "B()", FeaturesResources.constructor),
+ Diagnostic(RudeEditKind.ChangingAccessibility, "B()", FeaturesResources.constructor),
Diagnostic(RudeEditKind.Delete, "class B", DeletedSymbolDisplay(CSharpFeaturesResources.destructor, "~B()")));
}
@@ -7682,15 +7948,15 @@ public void InstanceCtorDelete_Public()
[InlineData("internal")]
[InlineData("private protected")]
[InlineData("protected internal")]
- public void InstanceCtorDelete_NonPublic(string visibility)
+ public void InstanceCtorDelete_NonPublic(string accessibility)
{
- var src1 = "class C { " + visibility + " C() { } }";
+ var src1 = "class C { " + accessibility + " C() { } }";
var src2 = "class C { }";
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
}
[Fact]
@@ -7810,7 +8076,7 @@ public void InstanceCtorInsert_Private_Implicit1()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "private C()", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "private C()", FeaturesResources.constructor));
}
[Fact]
@@ -7822,7 +8088,7 @@ public void InstanceCtorInsert_Private_Implicit2()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "C()", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "C()", FeaturesResources.constructor));
}
[Fact]
@@ -7834,7 +8100,7 @@ public void InstanceCtorInsert_Protected_PublicImplicit()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "protected C()", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "protected C()", FeaturesResources.constructor));
}
[Fact]
@@ -7846,7 +8112,7 @@ public void InstanceCtorInsert_Internal_PublicImplicit()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "internal C()", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "internal C()", FeaturesResources.constructor));
}
[Fact]
@@ -7858,7 +8124,7 @@ public void InstanceCtorInsert_Internal_ProtectedImplicit()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "internal C()", FeaturesResources.constructor));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "internal C()", FeaturesResources.constructor));
}
[Fact]
@@ -8012,12 +8278,12 @@ public void InstanceCtor_Partial_DeletePrivateInsertPublic()
new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
{
- // delete of the constructor in partial part will be reported as rude edit in the other document where it was inserted back with changed visibility
+ // delete of the constructor in partial part will be reported as rude edit in the other document where it was inserted back with changed accessibility
DocumentResults(
semanticEdits: NoSemanticEdits),
DocumentResults(
- diagnostics: new[] { Diagnostic(RudeEditKind.ModifiersUpdate, "public C()", FeaturesResources.constructor) }),
+ diagnostics: new[] { Diagnostic(RudeEditKind.ChangingAccessibility, "public C()", FeaturesResources.constructor) }),
});
}
@@ -8155,9 +8421,9 @@ public void InstanceCtor_Partial_InsertPublicDeletePrivate()
new[]
{
DocumentResults(
- diagnostics: new[] { Diagnostic(RudeEditKind.ModifiersUpdate, "public C()", FeaturesResources.constructor) }),
+ diagnostics: new[] { Diagnostic(RudeEditKind.ChangingAccessibility, "public C()", FeaturesResources.constructor) }),
- // delete of the constructor in partial part will be reported as rude in the the other document where it was inserted with changed visibility
+ // delete of the constructor in partial part will be reported as rude in the the other document where it was inserted with changed accessibility
DocumentResults(),
});
}
@@ -8176,7 +8442,7 @@ public void InstanceCtor_Partial_InsertInternalDeletePrivate()
new[]
{
DocumentResults(
- diagnostics: new[] { Diagnostic(RudeEditKind.ModifiersUpdate, "internal C()", FeaturesResources.constructor) }),
+ diagnostics: new[] { Diagnostic(RudeEditKind.ChangingAccessibility, "internal C()", FeaturesResources.constructor) }),
DocumentResults(),
});
@@ -8581,23 +8847,6 @@ public void InstanceCtor_Partial_Implicit_Update()
});
}
- [WorkItem(2068, "https://github.com/dotnet/roslyn/issues/2068")]
- [Fact]
- public void Insert_ExternConstruct()
- {
- var src1 = "class C { }";
- var src2 = "class C { public extern C(); }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits(
- "Insert [public extern C();]@10",
- "Insert [()]@25");
-
- // The compiler generates an empty constructor.
- edits.VerifySemanticDiagnostics();
- }
-
[Fact]
public void ParameterlessConstructor_SemanticError_Delete1()
{
@@ -8616,7 +8865,7 @@ class C
// The compiler interprets D() as a constructor declaration.
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
}
[Fact]
@@ -9070,7 +9319,7 @@ public void FieldInitializerUpdate_InstanceCtorUpdate_Private()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
}
[Fact]
@@ -9082,7 +9331,7 @@ public void PropertyInitializerUpdate_InstanceCtorUpdate_Private()
var edits = GetTopEdits(src1, src2);
edits.VerifySemanticDiagnostics(
- Diagnostic(RudeEditKind.ChangingVisibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
+ Diagnostic(RudeEditKind.ChangingAccessibility, "class C", DeletedSymbolDisplay(FeaturesResources.constructor, "C()")));
}
[Fact]
@@ -10469,6 +10718,109 @@ public void FieldUpdate_FieldKind()
Diagnostic(RudeEditKind.FieldKindUpdate, "event Action a", CSharpFeaturesResources.event_field));
}
+ [Theory]
+ [InlineData("static")]
+ [InlineData("volatile")]
+ [InlineData("const")]
+ public void Field_Modifiers_Update(string oldModifiers, string newModifiers = "")
+ {
+ if (oldModifiers != "")
+ {
+ oldModifiers += " ";
+ }
+
+ if (newModifiers != "")
+ {
+ newModifiers += " ";
+ }
+
+ var src1 = "class C { " + oldModifiers + "int F = 0; }";
+ var src2 = "class C { " + newModifiers + "int F = 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [" + oldModifiers + "int F = 0;]@10 -> [" + newModifiers + "int F = 0;]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "F = 0", FeaturesResources.field));
+ }
+
+ [Fact]
+ public void Field_Modifier_Add_InsertDelete()
+ {
+ var srcA1 = "partial class C { }";
+ var srcB1 = "partial class C { int F; }";
+
+ var srcA2 = "partial class C { static int F; }";
+ var srcB2 = "partial class C { }";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(
+ diagnostics: new[]
+ {
+ Diagnostic(RudeEditKind.ModifiersUpdate, "F", FeaturesResources.field)
+ }),
+
+ DocumentResults(),
+ });
+ }
+
+ [Fact]
+ public void Field_Attribute_Add_InsertDelete()
+ {
+ var srcA1 = "partial class C { }";
+ var srcB1 = "partial class C { int F; }";
+
+ var srcA2 = "partial class C { [System.Obsolete]int F; }";
+ var srcB2 = "partial class C { }";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.F"))
+ }),
+
+ DocumentResults(),
+ },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ }
+
+ [Fact]
+ public void Field_FixedSize_Update()
+ {
+ var src1 = "struct S { public unsafe fixed byte bs[1]; }";
+ var src2 = "struct S { public unsafe fixed byte bs[2]; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [bs[1]]@36 -> [bs[2]]@36");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.FixedSizeFieldUpdate, "bs[2]", FeaturesResources.field));
+ }
+
+ [WorkItem(1120407, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1120407")]
+ [Fact]
+ public void Field_Const_Update()
+ {
+ var src1 = "class C { const int x = 0; }";
+ var src2 = "class C { const int x = 1; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [x = 0]@20 -> [x = 1]@20");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.Update, "x = 1", FeaturesResources.const_field));
+ }
+
[Fact]
public void EventFieldUpdate_VariableDeclarator()
{
@@ -10956,7 +11308,7 @@ public void FieldInsert_Static_NotSupportedByRuntime()
}
[Fact]
- public void FieldUpdate_AddAttribute_Multiple()
+ public void Field_Attribute_Add_NotSupportedByRuntime()
{
var src1 = @"
class C
@@ -10966,40 +11318,91 @@ class C
var src2 = @"
class C
{
- [System.Obsolete]public int a = 1, x = 1;
+ [System.Obsolete]public int a = 1, x = 1;
+}";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits(
+ "Update [public int a = 1, x = 1;]@18 -> [[System.Obsolete]public int a = 1, x = 1;]@18");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "a = 1", FeaturesResources.field));
+ }
+
+ [Fact]
+ public void Field_Attribute_Add()
+ {
+ var src1 = @"
+class C
+{
+ public int a;
+}";
+ var src2 = @"
+class C
+{
+ [System.Obsolete]public int a;
}";
var edits = GetTopEdits(src1, src2);
- edits.VerifyEdits(
- "Update [public int a = 1, x = 1;]@18 -> [[System.Obsolete]public int a = 1, x = 1;]@18");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ChangingAttributesNotSupportedByRuntime, "a = 1", FeaturesResources.field));
+ edits.VerifySemantics(
+ ActiveStatementsDescription.Empty,
+ new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a"))
+ },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
}
[Fact]
- public void FieldUpdate_AddAttribute_SupportedByRuntime()
+ public void Field_Attribute_Add_WithInitializer()
{
var src1 = @"
class C
{
- public int a;
+ int a;
}";
var src2 = @"
class C
{
- [System.Obsolete]public int a;
+ [System.Obsolete]int a = 0;
}";
var edits = GetTopEdits(src1, src2);
edits.VerifySemantics(
ActiveStatementsDescription.Empty,
- new[] {
- SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a"))
+ new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a")),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), preserveLocalVariables: true),
},
- capabilities: EditAndContinueTestHelpers.Net5RuntimeCapabilities | EditAndContinueCapabilities.ChangeCustomAttributes);
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
+ }
+
+ [Fact]
+ public void Field_Attribute_DeleteInsertUpdate_WithInitializer()
+ {
+ var srcA1 = "partial class C { int a = 1; }";
+ var srcB1 = "partial class C { }";
+
+ var srcA2 = "partial class C { }";
+ var srcB2 = "partial class C { [System.Obsolete]int a = 2; }";
+
+ EditAndContinueValidation.VerifySemantics(
+ new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
+ new[]
+ {
+ DocumentResults(),
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C.a"), preserveLocalVariables: true),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true)
+ }),
+ },
+ capabilities: EditAndContinueTestHelpers.Net6RuntimeCapabilities);
}
[Fact]
@@ -11118,6 +11521,35 @@ public void EventField_Partial_InsertDelete()
#region Properties
+ [Theory]
+ [InlineData("static")]
+ [InlineData("virtual")]
+ [InlineData("abstract")]
+ [InlineData("override")]
+ [InlineData("sealed override", "override")]
+ public void Property_Modifiers_Update(string oldModifiers, string newModifiers = "")
+ {
+ if (oldModifiers != "")
+ {
+ oldModifiers += " ";
+ }
+
+ if (newModifiers != "")
+ {
+ newModifiers += " ";
+ }
+
+ var src1 = "class C { " + oldModifiers + "int F => 0; }";
+ var src2 = "class C { " + newModifiers + "int F => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [" + oldModifiers + "int F => 0;]@10 -> [" + newModifiers + "int F => 0;]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int F", FeaturesResources.property_));
+ }
+
[Fact]
public void PropertyWithExpressionBody_Update()
{
@@ -11977,11 +12409,20 @@ public void AutoProperty_Partial_InsertDelete()
var srcA2 = "partial class C { int P { get; set; } int Q { get; init; } }";
var srcB2 = "partial class C { }";
+ // Accessors need to be updated even though they do not have an explicit body.
+ // There is still a sequence point generated for them whose location needs to be updated.
EditAndContinueValidation.VerifySemantics(
new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
{
- DocumentResults(),
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").SetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("Q").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("Q").SetMethod),
+ }),
DocumentResults(),
});
}
@@ -11995,12 +12436,19 @@ public void AutoPropertyWithInitializer_Partial_InsertDelete()
var srcA2 = "partial class C { int P { get; set; } = 1; }";
var srcB2 = "partial class C { }";
+ // Accessors need to be updated even though they do not have an explicit body.
+ // There is still a sequence point generated for them whose location needs to be updated.
EditAndContinueValidation.VerifySemantics(
new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
{
DocumentResults(
- semanticEdits: new[] { SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true) }),
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("P").SetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").InstanceConstructors.Single(), partialType: "C", preserveLocalVariables: true)
+ }),
DocumentResults(),
});
@@ -12026,10 +12474,114 @@ public void PropertyWithExpressionBody_Partial_InsertDeleteUpdate()
});
}
+ [Fact]
+ public void AutoProperty_ReadOnly_Add()
+ {
+ var src1 = @"
+struct S
+{
+ int P { get; }
+}";
+ var src2 = @"
+struct S
+{
+ readonly int P { get; }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifySemanticDiagnostics();
+ }
+
+ [Fact]
+ public void Property_InMutableStruct_ReadOnly_Add()
+ {
+ var src1 = @"
+struct S
+{
+ int P1 { get => 1; }
+ int P2 { get => 1; set {}}
+ int P3 { get => 1; set {}}
+ int P4 { get => 1; set {}}
+}";
+ var src2 = @"
+struct S
+{
+ readonly int P1 { get => 1; }
+ int P2 { readonly get => 1; set {}}
+ int P3 { get => 1; readonly set {}}
+ readonly int P4 { get => 1; set {}}
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.property_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.property_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "set", CSharpFeaturesResources.property_setter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "readonly get", CSharpFeaturesResources.property_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "readonly set", CSharpFeaturesResources.property_setter));
+ }
+
+ [Fact]
+ public void Property_InReadOnlyStruct_ReadOnly_Add()
+ {
+ // indent to align accessor bodies and avoid updates caused by sequence point location changes
+
+ var src1 = @"
+readonly struct S
+{
+ int P1 { get => 1; }
+ int P2 { get => 1; set {}}
+ int P3 { get => 1; set {}}
+ int P4 { get => 1; set {}}
+}";
+ var src2 = @"
+readonly struct S
+{
+ readonly int P1 { get => 1; }
+ int P2 { readonly get => 1; set {}}
+ int P3 { get => 1; readonly set {}}
+ readonly int P4 { get => 1; set {}}
+}";
+ var edits = GetTopEdits(src1, src2);
+
+ // updates only for accessors whose modifiers were explicitly updated
+ edits.VerifySemantics(new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMember("P2").GetMethod, preserveLocalVariables: false),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMember("P3").SetMethod, preserveLocalVariables: false)
+ });
+ }
+
#endregion
#region Indexers
+ [Theory]
+ [InlineData("virtual")]
+ [InlineData("abstract")]
+ [InlineData("override")]
+ [InlineData("sealed override", "override")]
+ public void Indexer_Modifiers_Update(string oldModifiers, string newModifiers = "")
+ {
+ if (oldModifiers != "")
+ {
+ oldModifiers += " ";
+ }
+
+ if (newModifiers != "")
+ {
+ newModifiers += " ";
+ }
+
+ var src1 = "class C { " + oldModifiers + "int this[int a] => 0; }";
+ var src2 = "class C { " + newModifiers + "int this[int a] => 0; }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [" + oldModifiers + "int this[int a] => 0;]@10 -> [" + newModifiers + "int this[int a] => 0;]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "int this[int a]", FeaturesResources.indexer_));
+ }
+
[Fact]
public void Indexer_GetterUpdate()
{
@@ -12694,49 +13246,6 @@ public void Indexer_Insert()
edits.VerifySemanticDiagnostics();
}
- [WorkItem(1120407, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1120407")]
- [Fact]
- public void ConstField_Update()
- {
- var src1 = "class C { const int x = 0; }";
- var src2 = "class C { const int x = 1; }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits("Update [x = 0]@20 -> [x = 1]@20");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.Update, "x = 1", FeaturesResources.const_field));
- }
-
- [Fact]
- public void ConstField_Delete()
- {
- var src1 = "class C { const int x = 0; }";
- var src2 = "class C { int x = 0; }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits("Update [const int x = 0;]@10 -> [int x = 0;]@10");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "int x = 0", FeaturesResources.field));
- }
-
- [Fact]
- public void ConstField_Add()
- {
- var src1 = "class C { int x = 0; }";
- var src2 = "class C { const int x = 0; }";
-
- var edits = GetTopEdits(src1, src2);
-
- edits.VerifyEdits("Update [int x = 0;]@10 -> [const int x = 0;]@10");
-
- edits.VerifyRudeDiagnostics(
- Diagnostic(RudeEditKind.ModifiersUpdate, "const int x = 0", FeaturesResources.const_field));
- }
-
[Fact]
public void Indexer_ReadOnlyRef_Parameter_InsertWhole()
{
@@ -12851,16 +13360,23 @@ public void IndexerInit_Partial_InsertDelete()
public void AutoIndexer_Partial_InsertDelete()
{
var srcA1 = "partial class C { }";
- var srcB1 = "partial class C { int this[int x] { get; set; } int Q { get; init; } }";
+ var srcB1 = "partial class C { int this[int x] { get; set; } }";
- var srcA2 = "partial class C { int this[int x] { get; set; } int Q { get; init; } }";
+ var srcA2 = "partial class C { int this[int x] { get; set; } }";
var srcB2 = "partial class C { }";
+ // Accessors need to be updated even though they do not have an explicit body.
+ // There is still a sequence point generated for them whose location needs to be updated.
EditAndContinueValidation.VerifySemantics(
new[] { GetTopEdits(srcA1, srcA2), GetTopEdits(srcB1, srcB2) },
new[]
{
- DocumentResults(),
+ DocumentResults(
+ semanticEdits: new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("this[]").GetMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("C").GetMember("this[]").SetMethod),
+ }),
DocumentResults(),
});
}
@@ -12897,10 +13413,116 @@ partial class C
});
}
+ [Fact]
+ public void AutoIndexer_ReadOnly_Add()
+ {
+ var src1 = @"
+struct S
+{
+ int this[int x] { get; }
+}";
+ var src2 = @"
+struct S
+{
+ readonly int this[int x] { get; }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifySemanticDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.indexer_getter));
+ }
+
+ [Fact]
+ public void Indexer_InMutableStruct_ReadOnly_Add()
+ {
+ var src1 = @"
+struct S
+{
+ int this[int x] { get => 1; }
+ int this[uint x] { get => 1; set {}}
+ int this[byte x] { get => 1; set {}}
+ int this[sbyte x] { get => 1; set {}}
+}";
+ var src2 = @"
+struct S
+{
+ readonly int this[int x] { get => 1; }
+ int this[uint x] { readonly get => 1; set {}}
+ int this[byte x] { get => 1; readonly set {}}
+ readonly int this[sbyte x] { get => 1; set {}}
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.indexer_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "get", CSharpFeaturesResources.indexer_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "set", CSharpFeaturesResources.indexer_setter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "readonly get", CSharpFeaturesResources.indexer_getter),
+ Diagnostic(RudeEditKind.ModifiersUpdate, "readonly set", CSharpFeaturesResources.indexer_setter));
+ }
+
+ [Fact]
+ public void Indexer_InReadOnlyStruct_ReadOnly_Add()
+ {
+ // indent to align accessor bodies and avoid updates caused by sequence point location changes
+
+ var src1 = @"
+readonly struct S
+{
+ int this[int x] { get => 1; }
+ int this[uint x] { get => 1; set {}}
+ int this[byte x] { get => 1; set {}}
+ int this[sbyte x] { get => 1; set {}}
+}";
+ var src2 = @"
+readonly struct S
+{
+ readonly int this[int x] { get => 1; }
+ int this[uint x] { readonly get => 1; set {}}
+ int this[byte x] { get => 1; readonly set {}}
+ readonly int this[sbyte x] { get => 1; set {}}
+}";
+ var edits = GetTopEdits(src1, src2);
+
+ // updates only for accessors whose modifiers were explicitly updated
+ edits.VerifySemantics(new[]
+ {
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMembers("this[]").Cast().Single(m => m.Parameters.Single().Type.Name == "UInt32").GetMethod, preserveLocalVariables: false),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMembers("this[]").Cast().Single(m => m.Parameters.Single().Type.Name == "Byte").SetMethod, preserveLocalVariables: false)
+ });
+ }
+
#endregion
#region Events
+ [Theory]
+ [InlineData("static")]
+ [InlineData("virtual")]
+ [InlineData("abstract")]
+ [InlineData("override")]
+ [InlineData("sealed override", "override")]
+ public void Event_Modifiers_Update(string oldModifiers, string newModifiers = "")
+ {
+ if (oldModifiers != "")
+ {
+ oldModifiers += " ";
+ }
+
+ if (newModifiers != "")
+ {
+ newModifiers += " ";
+ }
+
+ var src1 = "class C { " + oldModifiers + "event Action F { add {} remove {} } }";
+ var src2 = "class C { " + newModifiers + "event Action F { add {} remove {} } }";
+
+ var edits = GetTopEdits(src1, src2);
+
+ edits.VerifyEdits("Update [" + oldModifiers + "event Action F { add {} remove {} }]@10 -> [" + newModifiers + "event Action F { add {} remove {} }]@10");
+
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, newModifiers + "event Action F", FeaturesResources.event_));
+ }
+
[Fact]
public void EventAccessorReorder1()
{
@@ -13074,6 +13696,45 @@ public void Event_Partial_InsertDelete()
});
}
+ [Fact]
+ public void Event_InMutableStruct_ReadOnly_Add()
+ {
+ var src1 = @"
+struct S
+{
+ public event Action E { add {} remove {} }
+}";
+ var src2 = @"
+struct S
+{
+ public readonly event Action E { add {} remove {} }
+}";
+ var edits = GetTopEdits(src1, src2);
+ edits.VerifyRudeDiagnostics(
+ Diagnostic(RudeEditKind.ModifiersUpdate, "public readonly event Action E", FeaturesResources.event_));
+ }
+
+ [Fact]
+ public void Event_InReadOnlyStruct_ReadOnly_Add1()
+ {
+ var src1 = @"
+readonly struct S
+{
+ public event Action E { add {} remove {} }
+}";
+ var src2 = @"
+readonly struct S
+{
+ public readonly event Action E { add {} remove {} }
+}";
+ var edits = GetTopEdits(src1, src2);
+
+ // Currently, an edit is produced eventhough bodies nor IsReadOnly attribute have changed. Consider improving.
+ edits.VerifySemantics(
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMember("E").AddMethod),
+ SemanticEdit(SemanticEditKind.Update, c => c.GetMember("S").GetMember("E").RemoveMethod));
+ }
+
#endregion
#region Parameter
diff --git a/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs
index 66842a26d5565..5bc456ab6687f 100644
--- a/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs
+++ b/src/EditorFeatures/CSharpTest/EditorConfigSettings/DataProvider/DataProviderTests.cs
@@ -108,7 +108,7 @@ public void TestGettingCodeStyleSettingsProviderLanguageServiceAsync()
var model = new TestViewModel();
settingsProvider.RegisterViewModel(model);
var dataSnapShot = settingsProvider.GetCurrentDataSnapshot();
- Assert.Equal(29, dataSnapShot.Length);
+ Assert.Equal(30, dataSnapShot.Length);
}
[Fact, Trait(Traits.Feature, Traits.Features.EditorConfigUI)]
diff --git a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
index 792917787cdca..bcb254453e86a 100644
--- a/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
+++ b/src/EditorFeatures/CSharpTest/GenerateFromMembers/GenerateEqualsAndGetHashCodeFromMembers/GenerateEqualsAndGetHashCodeFromMembersTests.cs
@@ -35,7 +35,7 @@ private class TestWithDialog : VerifyCS.Test
public ImmutableArray MemberNames;
public Action> OptionsCallback;
- public override AdhocWorkspace CreateWorkspace()
+ protected override Workspace CreateWorkspaceImpl()
{
// 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());
@@ -98,15 +98,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(39916, "https://github.com/dotnet/roslyn/issues/39916")]
@@ -135,15 +133,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferExplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferExplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -179,15 +175,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -229,15 +223,13 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -273,15 +265,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -309,15 +299,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -345,15 +333,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -386,15 +372,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -426,15 +410,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -484,16 +466,14 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 0,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -551,15 +531,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -795,15 +773,13 @@ public override bool Equals(object obj)
}
";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = expected,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -860,16 +836,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -902,16 +876,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -955,16 +927,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1005,17 +975,15 @@ public override int GetHashCode()
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
MemberNames = ImmutableArray.Empty,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1088,16 +1056,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1130,16 +1096,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1180,16 +1144,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1374,16 +1336,14 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 0,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1411,15 +1371,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1447,15 +1405,13 @@ public override bool Equals(object obj)
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1488,16 +1444,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1530,16 +1484,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1580,16 +1532,14 @@ struct Bar
{
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1632,16 +1582,14 @@ struct Bar
public override int GetHashCode() => 0;
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1682,16 +1630,14 @@ struct Bar
{
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1724,16 +1670,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1766,16 +1710,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1816,16 +1758,14 @@ enum Bar
{
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1858,16 +1798,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1899,16 +1837,14 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = ImmutableArray.Create("a", "b"),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1942,16 +1878,14 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = ImmutableArray.Create("c", "b"),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -1983,16 +1917,14 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = ImmutableArray.Empty,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(17643, "https://github.com/dotnet/roslyn/issues/17643")]
@@ -2020,15 +1952,13 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(25690, "https://github.com/dotnet/roslyn/issues/25690")]
@@ -2188,17 +2118,15 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2278,17 +2206,15 @@ public override bool Equals(object obj)
public static bool operator {|CS0216:==|}(Program left, Program right) => true;
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId)),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2333,17 +2259,15 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2392,16 +2316,14 @@ enum Bar
{
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 0,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2466,16 +2388,14 @@ struct Bar : IEquatable
public static bool operator !=(Bar left, Bar right) => !(left == right);
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 0,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2510,17 +2430,15 @@ public bool Equals(Program other)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2711,17 +2629,15 @@ public bool Equals(Program other)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -2844,17 +2760,15 @@ public override bool Equals(object obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => Assert.Null(options.FirstOrDefault(i => i.Id == GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.ImplementIEquatableId)),
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -3063,16 +2977,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -3121,7 +3033,7 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedState =
@@ -3135,10 +3047,8 @@ public override int GetHashCode()
},
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(37297, "https://github.com/dotnet/roslyn/issues/37297")]
@@ -3186,7 +3096,7 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestState =
{
@@ -3211,10 +3121,8 @@ public override int GetHashCode()
},
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(37297, "https://github.com/dotnet/roslyn/issues/37297")]
@@ -3262,7 +3170,7 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestState =
{
@@ -3279,10 +3187,8 @@ public override int GetHashCode()
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -3338,7 +3244,7 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedState =
@@ -3352,10 +3258,8 @@ public override int GetHashCode()
},
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -3422,16 +3326,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(39916, "https://github.com/dotnet/roslyn/issues/39916")]
@@ -3499,16 +3401,14 @@ public override int GetHashCode()
}
}";
- var test = new VerifyCS.Test
+ await new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
CodeActionIndex = 1,
LanguageVersion = LanguageVersion.CSharp6,
- };
-
- test.Options.AddRange(PreferExplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferExplicitTypeWithInfo() },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateEqualsAndGetHashCode)]
@@ -3693,7 +3593,7 @@ public override bool Equals(object? obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedState =
@@ -3710,10 +3610,8 @@ public override bool Equals(object? obj)
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId),
LanguageVersion = LanguageVersion.Default,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(40053, "https://github.com/dotnet/roslyn/issues/40053")]
@@ -3761,17 +3659,15 @@ public override bool Equals(object? obj)
}
}";
- var test = new TestWithDialog
+ await new TestWithDialog
{
TestCode = code,
FixedCode = fixedCode,
MemberNames = default,
OptionsCallback = options => EnableOption(options, GenerateEqualsAndGetHashCodeFromMembersCodeRefactoringProvider.GenerateOperatorsId),
LanguageVersion = LanguageVersion.Default,
- };
-
- test.Options.AddRange(PreferImplicitTypeWithInfo());
- await test.RunAsync();
+ Options = { PreferImplicitTypeWithInfo() },
+ }.RunAsync();
}
[WorkItem(42574, "https://github.com/dotnet/roslyn/issues/42574")]
diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs
index 7e7b0806bdaea..511f26564b02e 100644
--- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs
+++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementExplicitlyTests.cs
@@ -15,7 +15,7 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface
{
- public partial class ImplementExplicitlyTests : AbstractCSharpCodeActionTest
+ public class ImplementExplicitlyTests : AbstractCSharpCodeActionTest
{
private const int SingleMember = 0;
private const int SameInterface = 1;
diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementImplicitlyTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementImplicitlyTests.cs
index 9e5cf1cf288a1..d46a05aa7684a 100644
--- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementImplicitlyTests.cs
+++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementImplicitlyTests.cs
@@ -16,7 +16,7 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface
{
- public partial class ImplementImplicitlyTests : AbstractCSharpCodeActionTest
+ public class ImplementImplicitlyTests : AbstractCSharpCodeActionTest
{
private const int SingleMember = 0;
private const int SameInterface = 1;
diff --git a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
index 433012586fa24..c8065add4eb18 100644
--- a/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
+++ b/src/EditorFeatures/CSharpTest/ImplementInterface/ImplementInterfaceTests.cs
@@ -3,37 +3,27 @@
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
-using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
-using Microsoft.CodeAnalysis.CSharp.ImplementInterface;
-using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
-using Microsoft.CodeAnalysis.Diagnostics;
-using Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Editor.UnitTests.Diagnostics.NamingStyles;
using Microsoft.CodeAnalysis.ImplementType;
using Microsoft.CodeAnalysis.Test.Utilities;
+using Microsoft.CodeAnalysis.Testing;
using Roslyn.Test.Utilities;
using Xunit;
-using Xunit.Abstractions;
+using VerifyCS = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.CSharpCodeFixVerifier<
+ Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer,
+ Microsoft.CodeAnalysis.CSharp.ImplementInterface.CSharpImplementInterfaceCodeFixProvider>;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface
{
- public partial class ImplementInterfaceTests : AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest
+ public class ImplementInterfaceTests
{
private readonly NamingStylesTestOptionSets _options = new NamingStylesTestOptionSets(LanguageNames.CSharp);
- public ImplementInterfaceTests(ITestOutputHelper logger)
- : base(logger)
- {
- }
-
- internal override (DiagnosticAnalyzer?, CodeFixProvider) CreateDiagnosticProviderAndFixer(Workspace workspace)
- => (null, new CSharpImplementInterfaceCodeFixProvider());
-
- private OptionsCollection AllOptionsOff
- => new OptionsCollection(GetLanguage())
+ private static OptionsCollection AllOptionsOff
+ => new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
{ CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
@@ -43,8 +33,8 @@ private OptionsCollection AllOptionsOff
{ CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
};
- private OptionsCollection AllOptionsOn
- => new OptionsCollection(GetLanguage())
+ private static OptionsCollection AllOptionsOn
+ => new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement },
{ CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement },
@@ -54,8 +44,8 @@ private OptionsCollection AllOptionsOn
{ CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.WhenPossibleWithSilentEnforcement },
};
- private OptionsCollection AccessorOptionsOn
- => new OptionsCollection(GetLanguage())
+ private static OptionsCollection AccessorOptionsOn
+ => new OptionsCollection(LanguageNames.CSharp)
{
{ CSharpCodeStyleOptions.PreferExpressionBodiedMethods, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
{ CSharpCodeStyleOptions.PreferExpressionBodiedConstructors, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
@@ -65,77 +55,52 @@ private OptionsCollection AccessorOptionsOn
{ CSharpCodeStyleOptions.PreferExpressionBodiedIndexers, CSharpCodeStyleOptions.NeverWithSilentEnforcement },
};
- private static readonly ParseOptions CSharp7_1 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1);
-
- private const string NullableAttributesCode = @"
-namespace System.Diagnostics.CodeAnalysis
-{
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
- internal sealed class AllowNullAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
- internal sealed class DisallowNullAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
- internal sealed class MaybeNullAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
- internal sealed class NotNullAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- internal sealed class MaybeNullWhenAttribute : Attribute
- {
- public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
- public bool ReturnValue { get; }
- }
-
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- internal sealed class NotNullWhenAttribute : Attribute
- {
- public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
- public bool ReturnValue { get; }
- }
-
- [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
- internal sealed class NotNullIfNotNullAttribute : Attribute
- {
- public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
- public string ParameterName { get; }
- }
-
- [AttributeUsage(AttributeTargets.Method, Inherited = false)]
- internal sealed class DoesNotReturnAttribute : Attribute { }
-
- [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
- internal sealed class DoesNotReturnIfAttribute : Attribute
- {
- public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
- public bool ParameterValue { get; }
- }
-}";
-
- internal async Task TestWithAllCodeStyleOptionsOffAsync(
+ internal static async Task TestWithAllCodeStyleOptionsOffAsync(
string initialMarkup, string expectedMarkup,
- int index = 0, ParseOptions? parseOptions = null)
+ (string equivalenceKey, int index)? codeAction = null)
{
- await TestAsync(initialMarkup, expectedMarkup, parseOptions, null,
- index, options: AllOptionsOff);
+ await new VerifyCS.Test
+ {
+ TestCode = initialMarkup,
+ FixedCode = expectedMarkup,
+ Options = { AllOptionsOff },
+ CodeActionEquivalenceKey = codeAction?.equivalenceKey,
+ CodeActionIndex = codeAction?.index,
+ }.RunAsync();
}
- internal async Task TestWithAllCodeStyleOptionsOnAsync(
- string initialMarkup, string expectedMarkup,
- int index = 0, ParseOptions? parseOptions = null)
+ internal static async Task TestWithAllCodeStyleOptionsOnAsync(string initialMarkup, string expectedMarkup)
{
- await TestAsync(initialMarkup, expectedMarkup, parseOptions, null,
- index, options: AllOptionsOn);
+ await new VerifyCS.Test
+ {
+ TestCode = initialMarkup,
+ FixedCode = expectedMarkup,
+ Options = { AllOptionsOn },
+ }.RunAsync();
}
- internal async Task TestWithAccessorCodeStyleOptionsOnAsync(
- string initialMarkup, string expectedMarkup,
- int index = 0, ParseOptions? parseOptions = null)
+ internal static async Task TestWithAccessorCodeStyleOptionsOnAsync(string initialMarkup, string expectedMarkup)
+ {
+ await new VerifyCS.Test
+ {
+ TestCode = initialMarkup,
+ FixedCode = expectedMarkup,
+ Options = { AccessorOptionsOn },
+ }.RunAsync();
+ }
+
+ private static async Task TestInRegularAndScriptAsync(
+ string initialMarkup,
+ string expectedMarkup,
+ (string equivalenceKey, int index)? codeAction = null)
{
- await TestAsync(initialMarkup, expectedMarkup, parseOptions, null,
- index, options: AccessorOptionsOn);
+ await new VerifyCS.Test
+ {
+ TestCode = initialMarkup,
+ FixedCode = expectedMarkup,
+ CodeActionEquivalenceKey = codeAction?.equivalenceKey,
+ CodeActionIndex = codeAction?.index,
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
@@ -147,7 +112,7 @@ await TestWithAllCodeStyleOptionsOffAsync(
void Method1();
}
-class Class : [|IInterface|]
+class Class : {|CS0535:IInterface|}
{
}",
@"interface IInterface
@@ -167,16 +132,18 @@ public void Method1()
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public async Task TestMethodInRecord()
{
- await TestWithAllCodeStyleOptionsOffAsync(
-@"interface IInterface
+ await new VerifyCS.Test
+ {
+ LanguageVersion = LanguageVersion.Preview,
+ TestCode = @"interface IInterface
{
void Method1();
}
-record Record : [|IInterface|]
+record Record : {|CS0535:IInterface|}
{
}",
-@"interface IInterface
+ FixedCode = @"interface IInterface
{
void Method1();
}
@@ -187,7 +154,8 @@ public void Method1()
{
throw new System.NotImplementedException();
}
-}", parseOptions: TestOptions.RegularPreview);
+}",
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
@@ -210,19 +178,21 @@ public NativeIntegerAttribute(bool[] flags)
}";
// Note: we're putting the attribute by hand to simulate metadata
- await TestWithAllCodeStyleOptionsOffAsync(
-@"interface IInterface
+ await new VerifyCS.Test
+ {
+ LanguageVersion = LanguageVersion.CSharp9,
+ TestCode = @"interface IInterface
{
- [return: System.Runtime.CompilerServices.NativeInteger(new[] { true, true })]
+ [return: {|CS8335:System.Runtime.CompilerServices.NativeInteger(new[] { true, true })|}]
(nint, nuint) Method(nint x, nuint x2);
}
-class Class : [|IInterface|]
+class Class : {|CS0535:IInterface|}
{
}" + nativeIntegerAttributeDefinition,
- @"interface IInterface
+ FixedCode = @"interface IInterface
{
- [return: System.Runtime.CompilerServices.NativeInteger(new[] { true, true })]
+ [return: {|CS8335:System.Runtime.CompilerServices.NativeInteger(new[] { true, true })|}]
(nint, nuint) Method(nint x, nuint x2);
}
@@ -232,7 +202,9 @@ class Class : IInterface
{
throw new System.NotImplementedException();
}
-}" + nativeIntegerAttributeDefinition);
+}" + nativeIntegerAttributeDefinition,
+ Options = { AllOptionsOff },
+ }.RunAsync();
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
@@ -244,7 +216,7 @@ await TestWithAllCodeStyleOptionsOffAsync(
(int, int) Method((string, string) x);
}
-class Class : [|IInterface|]
+class Class : {|CS0535:IInterface|}
{
}",
@"interface IInterface
@@ -272,7 +244,7 @@ interface I
{
ValueTuple