未验证 提交 82fffbc4 编写于 作者: R Rikki Gibson 提交者: GitHub

Merge pull request #36793 from dotnet/release/dev16.2

Flow dev16.2 to dev16.2-vs-deps
......@@ -3,9 +3,9 @@
<ProductDependencies>
</ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19324.24">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19326.2">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>062febd818fa51e82c7192782a6b6e6429cc81c8</Sha>
<Sha>4b3d46cc75969c4e2de5786ec2b10a430b26dd9f</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
......@@ -66,7 +66,6 @@ jobs:
script: |
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId)
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)"
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsInternalBuild)
Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild)
- task: PublishBuildArtifacts@1
displayName: Publish ReleaseConfigs Artifact
......
parameters:
enableSymbolValidation: true
stages:
- stage: IS_Publish
dependsOn: validate
variables:
- template: ../common-variables.yml
displayName: Internal Servicing
jobs:
- template: ../setup-maestro-vars.yml
- job:
displayName: Symbol Publishing
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id)
variables:
- group: DotNet-Symbol-Server-Pats
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Artifacts
inputs:
downloadType: specific files
matchingPattern: "*Artifacts*"
- task: PowerShell@2
displayName: Publish
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
/p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
/p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
/p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:Configuration=Release
- job:
displayName: Publish Assets
dependsOn: setupMaestroVars
variables:
- group: DotNet-Blob-Feed
- group: Publish-Build-Assets
- group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
buildType: current
artifactName: PackageArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Blob Artifacts
inputs:
buildType: current
artifactName: BlobArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Asset Manifests
inputs:
buildType: current
artifactName: AssetManifests
- task: PowerShell@2
displayName: Add Assets Location
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
/p:ChannelId=$(InternalServicing_30_Channel_Id)
/p:IsStableBuild=$(IsStableBuild)
/p:IsInternalBuild=$(IsInternalBuild)
/p:RepositoryName=$(Build.Repository.Name)
/p:CommitSha=$(Build.SourceVersion)
/p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
/p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
/p:BuildAssetRegistryToken='$(MaestroAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
/p:Configuration=Release
- task: NuGetCommand@2
displayName: Publish Packages to AzDO Feed
condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
inputs:
command: push
vstsFeed: $(AzDoFeedName)
packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
publishVstsFeed: $(AzDoFeedName)
- task: PowerShell@2
displayName: Publish Blobs to AzDO Feed
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
arguments: -FeedName $(AzDoFeedName)
-SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
-PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
enabled: false
- stage: IS_PublishValidation
displayName: Publish Validation
variables:
- template: ../common-variables.yml
jobs:
- template: ../setup-maestro-vars.yml
- ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
- job:
displayName: Symbol Availability
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
buildType: current
artifactName: PackageArtifacts
- task: PowerShell@2
displayName: Check Symbol Availability
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
- job:
displayName: Gather Drop
dependsOn: setupMaestroVars
variables:
BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.InternalServicing_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: PowerShell@2
displayName: Setup Darc CLI
inputs:
targetType: filePath
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
- task: PowerShell@2
displayName: Run Darc gather-drop
inputs:
targetType: inline
script: |
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
enabled: false
- template: ../promote-build.yml
parameters:
ChannelId: ${{ variables.InternalServicing_30_Channel_Id }}
......@@ -20,17 +20,10 @@ stages:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download PDB Artifacts
displayName: Download Artifacts
inputs:
buildType: current
artifactName: PDBArtifacts
continueOnError: true
- task: DownloadBuildArtifacts@0
displayName: Download Blob Artifacts
inputs:
buildType: current
artifactName: BlobArtifacts
downloadType: specific files
matchingPattern: "*Artifacts*"
- task: PowerShell@2
displayName: Publish
......@@ -44,13 +37,16 @@ stages:
/p:Configuration=Release
- job:
displayName: Publish to Static Feed
displayName: Publish Assets
dependsOn: setupMaestroVars
variables:
- group: DotNet-Blob-Feed
- group: Publish-Build-Assets
- group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicDevRelease_30_Channel_Id)
pool:
vmImage: 'windows-2019'
......@@ -74,22 +70,47 @@ stages:
artifactName: AssetManifests
- task: PowerShell@2
displayName: Publish
displayName: Add Assets Location
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet
/p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)'
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
/p:ChannelId=$(PublicDevRelease_30_Channel_Id)
/p:IsStableBuild=$(IsStableBuild)
/p:IsInternalBuild=$(IsInternalBuild)
/p:RepositoryName=$(Build.Repository.Name)
/p:CommitSha=$(Build.SourceVersion)
/p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
/p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
/p:BuildAssetRegistryToken='$(MaestroAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
/p:ArtifactsCategory='$(_DotNetArtifactsCategory)'
/p:OverrideAssetsWithSameName=true
/p:PassIfExistingItemIdentical=true
/p:Configuration=Release
- task: NuGetCommand@2
displayName: Publish Packages to AzDO Feed
condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
inputs:
command: push
vstsFeed: $(AzDoFeedName)
packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
publishVstsFeed: $(AzDoFeedName)
- task: PowerShell@2
displayName: Publish Blobs to AzDO Feed
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
arguments: -FeedName $(AzDoFeedName)
-SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
-PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
enabled: false
- stage: PublishValidation
displayName: Publish Validation
......@@ -139,7 +160,3 @@ stages:
targetType: inline
script: |
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
- template: ../promote-build.yml
parameters:
ChannelId: ${{ variables.PublicDevRelease_30_Channel_Id }}
parameters:
enableSymbolValidation: true
stages:
- stage: PubRel_Publish
dependsOn: validate
variables:
- template: ../common-variables.yml
displayName: Public Release
jobs:
- template: ../setup-maestro-vars.yml
- job:
displayName: Symbol Publishing
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id)
variables:
- group: DotNet-Symbol-Server-Pats
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Artifacts
inputs:
downloadType: specific files
matchingPattern: "*Artifacts*"
- task: PowerShell@2
displayName: Publish
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishToSymbolServers -restore -msbuildEngine dotnet
/p:DotNetSymbolServerTokenMsdl=$(microsoft-symbol-server-pat)
/p:DotNetSymbolServerTokenSymWeb=$(symweb-symbol-server-pat)
/p:PDBArtifactsDirectory='$(Build.ArtifactStagingDirectory)/PDBArtifacts/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:Configuration=Release
- job:
displayName: Publish Assets
dependsOn: setupMaestroVars
variables:
- group: DotNet-Blob-Feed
- group: Publish-Build-Assets
- group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
buildType: current
artifactName: PackageArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Blob Artifacts
inputs:
buildType: current
artifactName: BlobArtifacts
- task: DownloadBuildArtifacts@0
displayName: Download Asset Manifests
inputs:
buildType: current
artifactName: AssetManifests
- task: PowerShell@2
displayName: Publish
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
/p:ChannelId=$(PublicRelease_30_Channel_Id)
/p:IsStableBuild=$(IsStableBuild)
/p:IsInternalBuild=$(IsInternalBuild)
/p:RepositoryName=$(Build.Repository.Name)
/p:CommitSha=$(Build.SourceVersion)
/p:NugetPath=$(Agent.BuildDirectory)/Nuget/NuGet.exe
/p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
/p:BuildAssetRegistryToken='$(MaestroAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
/p:Configuration=Release
- task: NuGetCommand@2
displayName: Publish Packages to AzDO Feed
condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
inputs:
command: push
vstsFeed: $(AzDoFeedName)
packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
publishVstsFeed: $(AzDoFeedName)
- task: PowerShell@2
displayName: Publish Blobs to AzDO Feed
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
arguments: -FeedName $(AzDoFeedName)
-SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
-PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
enabled: false
- stage: PubRel_PublishValidation
displayName: Publish Validation
variables:
- template: ../common-variables.yml
jobs:
- template: ../setup-maestro-vars.yml
- ${{ if eq(parameters.enableSymbolValidation, 'true') }}:
- job:
displayName: Symbol Availability
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: DownloadBuildArtifacts@0
displayName: Download Package Artifacts
inputs:
buildType: current
artifactName: PackageArtifacts
- task: PowerShell@2
displayName: Check Symbol Availability
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/symbols-validation.ps1
arguments: -InputPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ -ExtractPath $(Agent.BuildDirectory)/Temp/ -DotnetSymbolVersion $(SymbolToolVersion)
- job:
displayName: Gather Drop
dependsOn: setupMaestroVars
variables:
BARBuildId: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicRelease_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
- task: PowerShell@2
displayName: Setup Darc CLI
inputs:
targetType: filePath
filePath: '$(Build.SourcesDirectory)/eng/common/darc-init.ps1'
- task: PowerShell@2
displayName: Run Darc gather-drop
inputs:
targetType: inline
script: |
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com/ --password $(MaestroAccessToken) --latest-location
enabled: false
- template: ../promote-build.yml
parameters:
ChannelId: ${{ variables.PublicRelease_30_Channel_Id }}
......@@ -8,14 +8,17 @@ stages:
- template: ../setup-maestro-vars.yml
- job:
displayName: Publish to Static Feed
displayName: Publish Assets
dependsOn: setupMaestroVars
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id)
variables:
- group: DotNet-Blob-Feed
- group: Publish-Build-Assets
- group: AzureDevOps-Artifact-Feeds-Pats
- name: BARBuildId
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.BARBuildId'] ]
- name: IsStableBuild
value: $[ dependencies.setupMaestroVars.outputs['setReleaseVars.IsStableBuild'] ]
condition: contains(dependencies.setupMaestroVars.outputs['setReleaseVars.InitialChannels'], variables.PublicValidationRelease_30_Channel_Id)
pool:
vmImage: 'windows-2019'
steps:
......@@ -38,21 +41,46 @@ stages:
artifactName: AssetManifests
- task: PowerShell@2
displayName: Publish
displayName: Add Assets Location
env:
AZURE_DEVOPS_EXT_PAT: $(dn-bot-dnceng-unviersal-packages-rw)
inputs:
filePath: eng\common\sdk-task.ps1
arguments: -task PublishToPackageFeed -restore -msbuildEngine dotnet
/p:AccountKeyToStaticFeed='$(dotnetfeed-storage-access-key-1)'
arguments: -task PublishArtifactsInManifest -restore -msbuildEngine dotnet
/p:ChannelId=$(PublicValidationRelease_30_Channel_Id)
/p:IsStableBuild=$(IsStableBuild)
/p:IsInternalBuild=$(IsInternalBuild)
/p:RepositoryName=$(Build.Repository.Name)
/p:CommitSha=$(Build.SourceVersion)
/p:NugetPath=$(Agent.BuildDirectory)\Nuget\NuGet.exe
/p:AzdoTargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:TargetFeedPAT='$(dn-bot-dnceng-unviersal-packages-rw)'
/p:AzureStorageTargetFeedPAT='$(dotnetfeed-storage-access-key-1)'
/p:BARBuildId=$(BARBuildId)
/p:MaestroApiEndpoint='https://maestro-prod.westus2.cloudapp.azure.com'
/p:BuildAssetRegistryToken='$(MaestroAccessToken)'
/p:ManifestsBasePath='$(Build.ArtifactStagingDirectory)/AssetManifests/'
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)/BlobArtifacts/'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts/'
/p:ArtifactsCategory='$(_DotNetArtifactsCategory)'
/p:OverrideAssetsWithSameName=true
/p:PassIfExistingItemIdentical=true
/p:BlobBasePath='$(Build.ArtifactStagingDirectory)\BlobArtifacts'
/p:PackageBasePath='$(Build.ArtifactStagingDirectory)\PackageArtifacts'
/p:Configuration=Release
- task: NuGetCommand@2
displayName: Publish Packages to AzDO Feed
condition: contains(variables['TargetAzDOFeed'], 'pkgs.visualstudio.com')
inputs:
command: push
vstsFeed: $(AzDoFeedName)
packagesToPush: $(Build.ArtifactStagingDirectory)\PackageArtifacts\*.nupkg
publishVstsFeed: $(AzDoFeedName)
- task: PowerShell@2
displayName: Publish Blobs to AzDO Feed
inputs:
filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-blobs-to-azdo.ps1
arguments: -FeedName $(AzDoFeedName)
-SourceFolderCollection $(Build.ArtifactStagingDirectory)/BlobArtifacts/
-PersonalAccessToken $(dn-bot-dnceng-unviersal-packages-rw)
enabled: false
- stage: PVR_PublishValidation
......@@ -85,7 +113,3 @@ stages:
targetType: inline
script: |
darc gather-drop --non-shipping --continue-on-error --id $(BARBuildId) --output-dir $(Agent.BuildDirectory)/Temp/Drop/ --bar-uri https://maestro-prod.westus2.cloudapp.azure.com --password $(MaestroAccessToken) --latest-location
- template: ../promote-build.yml
parameters:
ChannelId: ${{ variables.PublicValidationRelease_30_Channel_Id }}
......@@ -5,5 +5,14 @@ variables:
# .NET Tools - Validation
PublicValidationRelease_30_Channel_Id: 9
# .NET Core 3.0 Internal Servicing
InternalServicing_30_Channel_Id: 184
# .NET Core 3.0 Release
PublicRelease_30_Channel_Id: 19
# Whether the build is internal or not
IsInternalBuild: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }}
SourceLinkCLIVersion: 3.0.0
SymbolToolVersion: 1.0.1
......@@ -65,3 +65,7 @@ stages:
enableSymbolValidation: ${{ parameters.enableSymbolValidation }}
- template: \eng\common\templates\post-build\channels\public-validation-release.yml
- template: \eng\common\templates\post-build\channels\public-release.yml
- template: \eng\common\templates\post-build\channels\internal-servicing.yml
......@@ -25,4 +25,3 @@ jobs:
"Authorization" = "Bearer $(MaestroAccessToken)"
}
Invoke-RestMethod -Method Post -Headers $headers -Uri https://maestro-prod.westus2.cloudapp.azure.com/api/channels/$(ChannelId)/builds/$(BARBuildId)?api-version=2019-01-16
enabled: false
......@@ -28,10 +28,8 @@ jobs:
$Channels = ""
$Content | Select -Index 1 | ForEach-Object { $Channels += "$_ ," }
$IsInternalBuild = $Content | Select -Index 2
$IsStableBuild = $Content | Select -Index 3
$IsStableBuild = $Content | Select -Index 2
Write-PipelineSetVariable -Name 'BARBuildId' -Value $BarId
Write-PipelineSetVariable -Name 'InitialChannels' -Value "$Channels"
Write-PipelineSetVariable -Name 'IsInternalBuild' -Value $IsInternalBuild
Write-PipelineSetVariable -Name 'IsStableBuild' -Value $IsStableBuild
......@@ -7,6 +7,6 @@
"xcopy-msbuild": "16.0.0-alpha"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19324.24"
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19326.2"
}
}
......@@ -2883,6 +2883,7 @@ private FlowAnalysisAnnotations GetRValueAnnotations(Symbol symbol)
MethodSymbol method => method.ReturnTypeFlowAnalysisAnnotations,
PropertySymbol property => property.GetOwnOrInheritedGetMethod()?.ReturnTypeFlowAnalysisAnnotations ?? FlowAnalysisAnnotations.None,
ParameterSymbol parameter => parameter.FlowAnalysisAnnotations,
FieldSymbol field => field.FlowAnalysisAnnotations,
_ => FlowAnalysisAnnotations.None
};
......@@ -5216,15 +5217,18 @@ private FlowAnalysisAnnotations GetLValueAnnotations(BoundExpression expr)
return FlowAnalysisAnnotations.None;
}
var symbol = expr switch
var annotations = expr switch
{
BoundPropertyAccess property => property.PropertySymbol,
BoundIndexerAccess indexer => indexer.Indexer,
_ => null
BoundPropertyAccess property => getSetterAnnotations(property.PropertySymbol),
BoundIndexerAccess indexer => getSetterAnnotations(indexer.Indexer),
BoundFieldAccess field => field.FieldSymbol.FlowAnalysisAnnotations,
_ => FlowAnalysisAnnotations.None
};
var annotations = symbol?.GetOwnOrInheritedSetMethod()?.Parameters.Last()?.FlowAnalysisAnnotations ?? FlowAnalysisAnnotations.None;
return annotations & (FlowAnalysisAnnotations.DisallowNull | FlowAnalysisAnnotations.AllowNull);
static FlowAnalysisAnnotations getSetterAnnotations(PropertySymbol property)
=> property.GetOwnOrInheritedSetMethod()?.Parameters.Last()?.FlowAnalysisAnnotations ?? FlowAnalysisAnnotations.None;
}
private static bool UseLegacyWarnings(BoundExpression expr, TypeWithAnnotations exprType)
......
......@@ -33,6 +33,9 @@ public override string Name
get { return GeneratedNames.MakeAnonymousTypeBackingFieldName(_property.Name); }
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
=> FlowAnalysisAnnotations.None;
internal override bool HasSpecialName
{
get { return false; }
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
/// <summary>
/// Information decoded from well-known custom attributes applied on a field.
/// </summary>
internal sealed class FieldWellKnownAttributeData : CommonFieldWellKnownAttributeData
{
private bool _hasAllowNullAttribute;
public bool HasAllowNullAttribute
{
get
{
VerifySealed(expected: true);
return _hasAllowNullAttribute;
}
set
{
VerifySealed(expected: false);
_hasAllowNullAttribute = value;
SetDataStored();
}
}
private bool _hasDisallowNullAttribute;
public bool HasDisallowNullAttribute
{
get
{
VerifySealed(expected: true);
return _hasDisallowNullAttribute;
}
set
{
VerifySealed(expected: false);
_hasDisallowNullAttribute = value;
SetDataStored();
}
}
private bool _hasMaybeNullAttribute;
public bool HasMaybeNullAttribute
{
get
{
VerifySealed(expected: true);
return _hasMaybeNullAttribute;
}
set
{
VerifySealed(expected: false);
_hasMaybeNullAttribute = value;
SetDataStored();
}
}
private bool? _maybeNullWhenAttribute;
public bool? MaybeNullWhenAttribute
{
get
{
VerifySealed(expected: true);
return _maybeNullWhenAttribute;
}
set
{
VerifySealed(expected: false);
_maybeNullWhenAttribute = value;
SetDataStored();
}
}
private bool _hasNotNullAttribute;
public bool HasNotNullAttribute
{
get
{
VerifySealed(expected: true);
return _hasNotNullAttribute;
}
set
{
VerifySealed(expected: false);
_hasNotNullAttribute = value;
SetDataStored();
}
}
}
}
......@@ -56,6 +56,8 @@ public TypeWithAnnotations TypeWithAnnotations
}
}
public abstract FlowAnalysisAnnotations FlowAnalysisAnnotations { get; }
/// <summary>
/// Gets the type of this field.
/// </summary>
......
......@@ -20,6 +20,49 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE
/// </summary>
internal sealed class PEFieldSymbol : FieldSymbol
{
private struct PackedFlags
{
// Layout:
// |..............................|vvvvv|
//
// f = FlowAnalysisAnnotations. 5 bits (4 value bits + 1 completion bit).
private const int HasDisallowNullAttribute = 0x1 << 0;
private const int HasAllowNullAttribute = 0x1 << 1;
private const int HasMaybeNullAttribute = 0x1 << 2;
private const int HasNotNullAttribute = 0x1 << 3;
private const int FlowAnalysisAnnotationsCompletionBit = 0x1 << 4;
private int _bits;
public bool SetFlowAnalysisAnnotations(FlowAnalysisAnnotations value)
{
Debug.Assert((value & ~(FlowAnalysisAnnotations.DisallowNull | FlowAnalysisAnnotations.AllowNull | FlowAnalysisAnnotations.MaybeNull | FlowAnalysisAnnotations.NotNull)) == 0);
int bitsToSet = FlowAnalysisAnnotationsCompletionBit;
if ((value & FlowAnalysisAnnotations.DisallowNull) != 0) bitsToSet |= PackedFlags.HasDisallowNullAttribute;
if ((value & FlowAnalysisAnnotations.AllowNull) != 0) bitsToSet |= PackedFlags.HasAllowNullAttribute;
if ((value & FlowAnalysisAnnotations.MaybeNull) != 0) bitsToSet |= PackedFlags.HasMaybeNullAttribute;
if ((value & FlowAnalysisAnnotations.NotNull) != 0) bitsToSet |= PackedFlags.HasNotNullAttribute;
return ThreadSafeFlagOperations.Set(ref _bits, bitsToSet);
}
public bool TryGetFlowAnalysisAnnotations(out FlowAnalysisAnnotations value)
{
int theBits = _bits; // Read this.bits once to ensure the consistency of the value and completion flags.
value = FlowAnalysisAnnotations.None;
if ((theBits & PackedFlags.HasDisallowNullAttribute) != 0) value |= FlowAnalysisAnnotations.DisallowNull;
if ((theBits & PackedFlags.HasAllowNullAttribute) != 0) value |= FlowAnalysisAnnotations.AllowNull;
if ((theBits & PackedFlags.HasMaybeNullAttribute) != 0) value |= FlowAnalysisAnnotations.MaybeNull;
if ((theBits & PackedFlags.HasNotNullAttribute) != 0) value |= FlowAnalysisAnnotations.NotNull;
var result = (theBits & FlowAnalysisAnnotationsCompletionBit) != 0;
Debug.Assert(value == 0 || result);
return result;
}
}
private readonly FieldDefinitionHandle _handle;
private readonly string _name;
private readonly FieldAttributes _flags;
......@@ -36,6 +79,7 @@ internal sealed class PEFieldSymbol : FieldSymbol
private int _lazyFixedSize;
private NamedTypeSymbol _lazyFixedImplementationType;
private PEEventSymbol _associatedEventOpt;
private PackedFlags _packedFlags;
internal PEFieldSymbol(
PEModuleSymbol moduleSymbol,
......@@ -48,6 +92,7 @@ internal sealed class PEFieldSymbol : FieldSymbol
_handle = fieldDef;
_containingType = containingType;
_packedFlags = new PackedFlags();
try
{
......@@ -272,6 +317,30 @@ internal override TypeWithAnnotations GetFieldType(ConsList<FieldSymbol> fieldsB
return _lazyType.Value;
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
{
get
{
FlowAnalysisAnnotations value;
if (!_packedFlags.TryGetFlowAnalysisAnnotations(out value))
{
value = DecodeFlowAnalysisAttributes(_containingType.ContainingPEModule.Module, _handle);
_packedFlags.SetFlowAnalysisAnnotations(value);
}
return value;
}
}
private static FlowAnalysisAnnotations DecodeFlowAnalysisAttributes(PEModule module, FieldDefinitionHandle handle)
{
FlowAnalysisAnnotations annotations = FlowAnalysisAnnotations.None;
if (module.HasAttribute(handle, AttributeDescription.AllowNullAttribute)) annotations |= FlowAnalysisAnnotations.AllowNull;
if (module.HasAttribute(handle, AttributeDescription.DisallowNullAttribute)) annotations |= FlowAnalysisAnnotations.DisallowNull;
if (module.HasAttribute(handle, AttributeDescription.MaybeNullAttribute)) annotations |= FlowAnalysisAnnotations.MaybeNull;
if (module.HasAttribute(handle, AttributeDescription.NotNullAttribute)) annotations |= FlowAnalysisAnnotations.NotNull;
return annotations;
}
public override bool IsFixedSizeBuffer
{
get
......
......@@ -98,7 +98,7 @@ private CustomAttributesBag<CSharpAttributeData> GetAttributesBag()
/// <remarks>
/// Forces binding and decoding of attributes.
/// </remarks>
protected CommonFieldWellKnownAttributeData GetDecodedWellKnownAttributeData()
protected FieldWellKnownAttributeData GetDecodedWellKnownAttributeData()
{
var attributesBag = _lazyCustomAttributesBag;
if (attributesBag == null || !attributesBag.IsDecodedWellKnownAttributeDataComputed)
......@@ -106,7 +106,7 @@ protected CommonFieldWellKnownAttributeData GetDecodedWellKnownAttributeData()
attributesBag = this.GetAttributesBag();
}
return (CommonFieldWellKnownAttributeData)attributesBag.DecodedWellKnownAttributeData;
return (FieldWellKnownAttributeData)attributesBag.DecodedWellKnownAttributeData;
}
internal sealed override CSharpAttributeData EarlyDecodeWellKnownAttribute(ref EarlyDecodeWellKnownAttributeArguments<EarlyWellKnownAttributeBinder, NamedTypeSymbol, AttributeSyntax, AttributeLocation> arguments)
......@@ -162,11 +162,11 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu
if (attribute.IsTargetAttribute(this, AttributeDescription.SpecialNameAttribute))
{
arguments.GetOrCreateData<CommonFieldWellKnownAttributeData>().HasSpecialNameAttribute = true;
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasSpecialNameAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NonSerializedAttribute))
{
arguments.GetOrCreateData<CommonFieldWellKnownAttributeData>().HasNonSerializedAttribute = true;
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasNonSerializedAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.FieldOffsetAttribute))
{
......@@ -188,12 +188,12 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu
// Set field offset even if the attribute specifies an invalid value, so that
// post-validation knows that the attribute is applied and reports better errors.
arguments.GetOrCreateData<CommonFieldWellKnownAttributeData>().SetFieldOffset(offset);
arguments.GetOrCreateData<FieldWellKnownAttributeData>().SetFieldOffset(offset);
}
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.MarshalAsAttribute))
{
MarshalAsAttributeDecoder<CommonFieldWellKnownAttributeData, AttributeSyntax, CSharpAttributeData, AttributeLocation>.Decode(ref arguments, AttributeTargets.Field, MessageProvider.Instance);
MarshalAsAttributeDecoder<FieldWellKnownAttributeData, AttributeSyntax, CSharpAttributeData, AttributeLocation>.Decode(ref arguments, AttributeTargets.Field, MessageProvider.Instance);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.DynamicAttribute))
{
......@@ -232,6 +232,38 @@ internal override void DecodeWellKnownAttribute(ref DecodeWellKnownAttributeArgu
// NullableAttribute should not be set explicitly.
arguments.Diagnostics.Add(ErrorCode.ERR_ExplicitNullableAttribute, arguments.AttributeSyntaxOpt.Location);
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.AllowNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasAllowNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.DisallowNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasDisallowNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.MaybeNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasMaybeNullAttribute = true;
}
else if (attribute.IsTargetAttribute(this, AttributeDescription.NotNullAttribute))
{
arguments.GetOrCreateData<FieldWellKnownAttributeData>().HasNotNullAttribute = true;
}
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
=> DecodeFlowAnalysisAttributes(GetDecodedWellKnownAttributeData());
private static FlowAnalysisAnnotations DecodeFlowAnalysisAttributes(FieldWellKnownAttributeData attributeData)
{
var annotations = FlowAnalysisAnnotations.None;
if (attributeData != null)
{
if (attributeData.HasAllowNullAttribute) annotations |= FlowAnalysisAnnotations.AllowNull;
if (attributeData.HasDisallowNullAttribute) annotations |= FlowAnalysisAnnotations.DisallowNull;
if (attributeData.HasMaybeNullAttribute) annotations |= FlowAnalysisAnnotations.MaybeNull;
if (attributeData.HasNotNullAttribute) annotations |= FlowAnalysisAnnotations.NotNull;
}
return annotations;
}
/// <summary>
......@@ -243,7 +275,7 @@ private void VerifyConstantValueMatches(ConstantValue attrValue, ref DecodeWellK
{
if (!attrValue.IsBad)
{
var data = arguments.GetOrCreateData<CommonFieldWellKnownAttributeData>();
var data = arguments.GetOrCreateData<FieldWellKnownAttributeData>();
ConstantValue constValue;
if (this.IsConst)
......@@ -295,7 +327,7 @@ internal override void PostDecodeWellKnownAttributes(ImmutableArray<CSharpAttrib
Debug.Assert(_lazyCustomAttributesBag.IsDecodedWellKnownAttributeDataComputed);
Debug.Assert(symbolPart == AttributeLocation.None);
var data = (CommonFieldWellKnownAttributeData)decodedData;
var data = (FieldWellKnownAttributeData)decodedData;
int? fieldOffset = data != null ? data.Offset : null;
if (fieldOffset.HasValue)
......
......@@ -77,6 +77,9 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
internal abstract override TypeWithAnnotations GetFieldType(ConsList<FieldSymbol> fieldsBeingBound);
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
=> FlowAnalysisAnnotations.None;
public override string Name
{
get { return _name; }
......
......@@ -40,6 +40,11 @@ public override bool IsImplicitlyDeclared
get { return _underlyingField.IsImplicitlyDeclared; }
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
{
get { return _underlyingField.FlowAnalysisAnnotations; }
}
public override Accessibility DeclaredAccessibility
{
get
......
......@@ -20876,6 +20876,95 @@ public class CClass<TClass> where TClass : class
);
}
[Fact]
public void MaybeNull_Field()
{
// Warn on misused nullability attributes (f2, f3, f4, f5)? https://github.com/dotnet/roslyn/issues/36073
var lib_cs =
@"using System.Diagnostics.CodeAnalysis;
public class COpen<TOpen>
{
[MaybeNull]public TOpen f1 = default!;
}
public class CClass<TClass> where TClass : class
{
[MaybeNull]public TClass f2 = null!;
[MaybeNull]public TClass? f3 = null;
}
public class CStruct<TStruct> where TStruct : struct
{
[MaybeNull]public TStruct f4;
[MaybeNull]public TStruct? f5;
}
";
var lib = CreateNullableCompilation(new[] { MaybeNullAttributeDefinition, lib_cs });
var source = @"
class C
{
static void M1<T>(T t1)
{
new COpen<T>().f1.ToString(); // 1
}
static void M2<T>() where T : class
{
new COpen<T>().f1.ToString(); // 2
new CClass<T>().f2.ToString(); // 3
new CClass<T>().f3.ToString(); // 4
}
static void M4<T>(T t4) where T : struct
{
new COpen<T>().f1.ToString();
new CStruct<T>().f4.ToString();
new CStruct<T>().f5.Value.ToString(); // 5
}
}";
var expected = new[]
{
// (6,9): warning CS8602: Dereference of a possibly null reference.
// new COpen<T>().f1.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "new COpen<T>().f1").WithLocation(6, 9),
// (10,9): warning CS8602: Dereference of a possibly null reference.
// new COpen<T>().f1.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "new COpen<T>().f1").WithLocation(10, 9),
// (11,9): warning CS8602: Dereference of a possibly null reference.
// new CClass<T>().f2.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "new CClass<T>().f2").WithLocation(11, 9),
// (12,9): warning CS8602: Dereference of a possibly null reference.
// new CClass<T>().f3.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "new CClass<T>().f3").WithLocation(12, 9),
// (18,9): warning CS8629: Nullable value type may be null.
// new CStruct<T>().f5.Value.ToString(); // 5
Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "new CStruct<T>().f5").WithLocation(18, 9)
};
var comp = CreateNullableCompilation(source, references: new[] { lib.EmitToImageReference() });
comp.VerifyDiagnostics(expected);
var comp2 = CreateNullableCompilation(new[] { source, lib_cs, MaybeNullAttributeDefinition });
comp2.VerifyDiagnostics(expected);
CompileAndVerify(comp2, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator);
void symbolValidator(ModuleSymbol m)
{
bool isSource = !(m is PEModuleSymbol);
var copen = (NamedTypeSymbol)m.GlobalNamespace.GetMember("COpen");
var field = copen.GetMembers().OfType<FieldSymbol>().Single();
var fieldAttributes = field.GetAttributes().Select(a => a.ToString());
if (isSource)
{
AssertEx.Equal(new[] { "System.Diagnostics.CodeAnalysis.MaybeNullAttribute" }, fieldAttributes);
}
else
{
AssertEx.Equal(new[] { "System.Runtime.CompilerServices.NullableAttribute(1)", "System.Diagnostics.CodeAnalysis.MaybeNullAttribute" }, fieldAttributes);
}
}
}
[Fact]
public void MaybeNullWhenTrue_OnImplicitReferenceConversion()
{
......@@ -26331,6 +26420,121 @@ static void M1<T>(T t1)
comp2.VerifyDiagnostics(expected);
}
[Fact]
public void AllowNull_Field()
{
// Warn on misused nullability attributes (f3, f4, f5)? https://github.com/dotnet/roslyn/issues/36073
var lib_cs =
@"using System.Diagnostics.CodeAnalysis;
public class COpen<TOpen>
{
[AllowNull]public TOpen f1 = default;
}
public class CClass<TClass> where TClass : class
{
[AllowNull]public TClass f2 = null;
[AllowNull]public TClass? f3 = null;
}
public class CStruct<TStruct> where TStruct : struct
{
[AllowNull]public TStruct f4;
[AllowNull]public TStruct? f5;
}
";
var lib = CreateNullableCompilation(new[] { AllowNullAttributeDefinition, lib_cs });
var source = @"
class C
{
static void M1<T>(T t1)
{
new COpen<T>().f1 = t1;
}
static void M2<T>(T t2) where T : class
{
new COpen<T>().f1 = t2;
new CClass<T>().f2 = t2;
new CClass<T>().f3 = t2;
t2 = null; // 1
new COpen<T>().f1 = t2;
new CClass<T>().f2 = t2;
new CClass<T>().f3 = t2;
}
static void M3<T>(T? t3) where T : class
{
new COpen<T>().f1 = t3;
new CClass<T>().f2 = t3;
new CClass<T>().f3 = t3;
if (t3 == null) return;
new COpen<T>().f1 = t3;
new CClass<T>().f2 = t3;
new CClass<T>().f3 = t3;
}
static void M4<T>(T t4) where T : struct
{
new COpen<T>().f1 = t4;
new CStruct<T>().f4 = t4;
}
static void M5<T>(T? t5) where T : struct
{
new COpen<T?>().f1 = t5;
new CStruct<T>().f5 = t5;
if (t5 == null) return;
new COpen<T?>().f1 = t5;
new CStruct<T>().f5 = t5;
}
}";
var expected = new[]
{
// (13,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// t2 = null; // 1
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(13, 14)
};
var comp = CreateNullableCompilation(source, references: new[] { lib.EmitToImageReference() });
comp.VerifyDiagnostics(expected);
var comp2 = CreateNullableCompilation(new[] { source, lib_cs, AllowNullAttributeDefinition });
comp2.VerifyDiagnostics(expected);
CompileAndVerify(comp2, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator);
void symbolValidator(ModuleSymbol m)
{
bool isSource = !(m is PEModuleSymbol);
var copen = (NamedTypeSymbol)m.GlobalNamespace.GetMember("COpen");
var field = copen.GetMembers().OfType<FieldSymbol>().Single();
var fieldAttributes = field.GetAttributes().Select(a => a.ToString());
if (isSource)
{
AssertEx.Equal(new[] { "System.Diagnostics.CodeAnalysis.AllowNullAttribute" }, fieldAttributes);
}
else
{
AssertEx.Equal(new[] { "System.Runtime.CompilerServices.NullableAttribute(1)", "System.Diagnostics.CodeAnalysis.AllowNullAttribute" }, fieldAttributes);
}
}
}
[Fact]
public void AllowNull_Field_NullInitializer()
{
var source =
@"using System.Diagnostics.CodeAnalysis;
public class C
{
[AllowNull]public string field = null;
string M() => field.ToString();
}
";
var comp = CreateNullableCompilation(new[] { AllowNullAttributeDefinition, source });
comp.VerifyDiagnostics();
}
[Fact]
public void AllowNull_Operator_CompoundAssignment()
{
......@@ -27247,7 +27451,7 @@ static void M1(string? s, string s2)
comp2.VerifyDiagnostics(expected);
}
[Fact]
[Fact, WorkItem(36703, "https://github.com/dotnet/roslyn/issues/36703")]
public void DisallowNull_RefReturnValue_05()
{
var source0 =
......@@ -27532,6 +27736,217 @@ public class C
comp.VerifyDiagnostics();
}
[Fact]
public void DisallowNull_Field()
{
// Warn on misused nullability attributes (f2, f3, f4)? https://github.com/dotnet/roslyn/issues/36073
var lib_cs =
@"using System.Diagnostics.CodeAnalysis;
public class COpen<TOpen>
{
[DisallowNull]public TOpen f1 = default!;
}
public class CClass<TClass> where TClass : class
{
[DisallowNull]public TClass f2 = null!;
[DisallowNull]public TClass? f3 = null!;
}
public class CStruct<TStruct> where TStruct : struct
{
[DisallowNull]public TStruct f4;
[DisallowNull]public TStruct? f5;
}
";
var lib = CreateNullableCompilation(new[] { DisallowNullAttributeDefinition, lib_cs });
var source = @"
class C
{
static void M1<T>(T t1)
{
new COpen<T>().f1 = t1;
}
static void M2<T>(T t2) where T : class
{
new COpen<T>().f1 = t2;
new CClass<T>().f2 = t2;
new CClass<T>().f3 = t2;
t2 = null; // 1
new COpen<T>().f1 = t2; // 2
new CClass<T>().f2 = t2; // 3
new CClass<T>().f3 = t2; // 4
}
static void M3<T>(T? t3) where T : class
{
new COpen<T>().f1 = t3; // 5
new CClass<T>().f2 = t3; // 6
new CClass<T>().f3 = t3; // 7
if (t3 == null) return;
new COpen<T>().f1 = t3;
new CClass<T>().f2 = t3;
new CClass<T>().f3 = t3;
}
static void M4<T>(T t4) where T : struct
{
new COpen<T>().f1 = t4;
new CStruct<T>().f4 = t4;
}
static void M5<T>(T? t5) where T : struct
{
new COpen<T?>().f1 = t5; // 8
new CStruct<T>().f5 = t5; // 9
if (t5 == null) return;
new COpen<T?>().f1 = t5;
new CStruct<T>().f5 = t5;
}
static void M6<T>([System.Diagnostics.CodeAnalysis.MaybeNull]T t6) where T : class
{
new CClass<T>().f2 = t6;
}
static void M7<T>([System.Diagnostics.CodeAnalysis.NotNull]T? t7) where T : class
{
new CClass<T>().f2 = t7; // 10
}
static void M8<T>([System.Diagnostics.CodeAnalysis.AllowNull]T t8) where T : class
{
new CClass<T>().f2 = t8; // no warning, we currently don't honor the attribute on t6 within the method body
}
}";
// we currently don't honor the attribute on t6 within the method body https://github.com/dotnet/roslyn/issues/36039
var expected = new[]
{
// (13,14): warning CS8600: Converting null literal or possible null value to non-nullable type.
// t2 = null; // 1
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "null").WithLocation(13, 14),
// (14,29): warning CS8601: Possible null reference assignment.
// new COpen<T>().f1 = t2; // 2
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t2").WithLocation(14, 29),
// (15,30): warning CS8601: Possible null reference assignment.
// new CClass<T>().f2 = t2; // 3
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t2").WithLocation(15, 30),
// (16,30): warning CS8601: Possible null reference assignment.
// new CClass<T>().f3 = t2; // 4
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t2").WithLocation(16, 30),
// (20,29): warning CS8601: Possible null reference assignment.
// new COpen<T>().f1 = t3; // 5
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t3").WithLocation(20, 29),
// (21,30): warning CS8601: Possible null reference assignment.
// new CClass<T>().f2 = t3; // 6
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t3").WithLocation(21, 30),
// (22,30): warning CS8601: Possible null reference assignment.
// new CClass<T>().f3 = t3; // 7
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t3").WithLocation(22, 30),
// (35,30): warning CS8607: A possible null value may not be passed to a target marked with the [DisallowNull] attribute
// new COpen<T?>().f1 = t5; // 8
Diagnostic(ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment, "t5").WithLocation(35, 30),
// (36,31): warning CS8607: A possible null value may not be passed to a target marked with the [DisallowNull] attribute
// new CStruct<T>().f5 = t5; // 9
Diagnostic(ErrorCode.WRN_DisallowNullAttributeForbidsMaybeNullAssignment, "t5").WithLocation(36, 31),
// (47,30): warning CS8601: Possible null reference assignment.
// new CClass<T>().f2 = t7; // 10
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "t7").WithLocation(47, 30)
};
var comp = CreateNullableCompilation(new[] { source, AllowNullAttributeDefinition, MaybeNullAttributeDefinition, NotNullAttributeDefinition },
references: new[] { lib.EmitToImageReference() });
comp.VerifyDiagnostics(expected);
var comp2 = CreateNullableCompilation(new[] { source, lib_cs, DisallowNullAttributeDefinition, AllowNullAttributeDefinition, MaybeNullAttributeDefinition, NotNullAttributeDefinition });
comp2.VerifyDiagnostics(expected);
CompileAndVerify(comp2, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator);
void symbolValidator(ModuleSymbol m)
{
bool isSource = !(m is PEModuleSymbol);
var copen = (NamedTypeSymbol)m.GlobalNamespace.GetMember("COpen");
var field = copen.GetMembers().OfType<FieldSymbol>().Single();
var fieldAttributes = field.GetAttributes().Select(a => a.ToString());
if (isSource)
{
AssertEx.Equal(new[] { "System.Diagnostics.CodeAnalysis.DisallowNullAttribute" }, fieldAttributes);
}
else
{
AssertEx.Equal(new[] { "System.Runtime.CompilerServices.NullableAttribute(1)", "System.Diagnostics.CodeAnalysis.DisallowNullAttribute" }, fieldAttributes);
}
}
}
[Fact]
public void DisallowNull_AndOtherAnnotations_StaticField()
{
var lib_cs =
@"using System.Diagnostics.CodeAnalysis;
public class C
{
[DisallowNull]public static string? disallowNull = null!;
[AllowNull]public static string allowNull = null;
[MaybeNull]public static string maybeNull = null!;
[NotNull]public static string? notNull = null;
}
";
var lib = CreateNullableCompilation(new[] { DisallowNullAttributeDefinition, AllowNullAttributeDefinition, MaybeNullAttributeDefinition, NotNullAttributeDefinition, lib_cs });
var source = @"
class D
{
static void M()
{
C.disallowNull = null; // 1
C.allowNull = null;
C.maybeNull.ToString(); // 2
C.notNull.ToString();
}
}";
var expected = new[]
{
// (6,26): warning CS8625: Cannot convert null literal to non-nullable reference type.
// C.disallowNull = null; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(6, 26),
// (8,9): warning CS8602: Dereference of a possibly null reference.
// C.maybeNull.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "C.maybeNull").WithLocation(8, 9)
};
var comp = CreateNullableCompilation(source, references: new[] { lib.EmitToImageReference() });
comp.VerifyDiagnostics(expected);
var comp2 = CreateNullableCompilation(new[] { source, lib_cs, DisallowNullAttributeDefinition, AllowNullAttributeDefinition, MaybeNullAttributeDefinition, NotNullAttributeDefinition });
comp2.VerifyDiagnostics(expected);
}
[Fact]
public void DisallowNull_Field_NullInitializer()
{
var source =
@"using System.Diagnostics.CodeAnalysis;
public class C
{
[DisallowNull]public string? field = null; // 1
void M()
{
field.ToString(); // 2
}
}
";
var comp = CreateNullableCompilation(new[] { DisallowNullAttributeDefinition, source });
comp.VerifyDiagnostics(
// (4,42): warning CS8625: Cannot convert null literal to non-nullable reference type.
// [DisallowNull]public string? field = null; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(4, 42),
// (8,9): warning CS8602: Dereference of a possibly null reference.
// field.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "field").WithLocation(8, 9)
);
}
[Fact]
public void AllowNull_Parameter_NullDefaultValue()
{
......@@ -30271,6 +30686,77 @@ public class CClass2<TClass> where TClass : class
comp.VerifyDiagnostics();
}
[Fact]
public void NotNull_Field()
{
// Warn on misused nullability attributes (f2, f3, f4, f5)? https://github.com/dotnet/roslyn/issues/36073
var lib_cs =
@"using System.Diagnostics.CodeAnalysis;
public class COpen<TOpen>
{
[NotNull]public TOpen f1 = default!;
}
public class CClass<TClass> where TClass : class
{
[NotNull]public TClass f2 = null!;
[NotNull]public TClass? f3 = null;
}
public class CStruct<TStruct> where TStruct : struct
{
[NotNull]public TStruct f4;
[NotNull]public TStruct? f5;
}
";
var lib = CreateNullableCompilation(new[] { NotNullAttributeDefinition, lib_cs });
var source = @"
class C
{
static void M1<T>(T t1)
{
new COpen<T>().f1.ToString();
}
static void M2<T>() where T : class
{
new COpen<T>().f1.ToString();
new CClass<T>().f2.ToString();
new CClass<T>().f3.ToString();
}
static void M4<T>(T t4) where T : struct
{
new COpen<T>().f1.ToString();
new CStruct<T>().f4.ToString();
new CStruct<T>().f5.Value.ToString();
}
}";
var comp = CreateNullableCompilation(source, references: new[] { lib.EmitToImageReference() });
comp.VerifyDiagnostics();
var comp2 = CreateNullableCompilation(new[] { source, lib_cs, NotNullAttributeDefinition });
comp2.VerifyDiagnostics();
CompileAndVerify(comp2, sourceSymbolValidator: symbolValidator, symbolValidator: symbolValidator);
void symbolValidator(ModuleSymbol m)
{
bool isSource = !(m is PEModuleSymbol);
var copen = (NamedTypeSymbol)m.GlobalNamespace.GetMember("COpen");
var field = copen.GetMembers().OfType<FieldSymbol>().Single();
var fieldAttributes = field.GetAttributes().Select(a => a.ToString());
if (isSource)
{
AssertEx.Equal(new[] { "System.Diagnostics.CodeAnalysis.NotNullAttribute" }, fieldAttributes);
}
else
{
AssertEx.Equal(new[] { "System.Runtime.CompilerServices.NullableAttribute(1)", "System.Diagnostics.CodeAnalysis.NotNullAttribute" }, fieldAttributes);
}
}
}
[Fact, WorkItem(35949, "https://github.com/dotnet/roslyn/issues/35949")]
public void NotNull_Complexity()
{
......@@ -24,8 +24,10 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.AddUsing
public class AddUsingNuGetTests : AbstractAddUsingTests
{
const string NugetOrgSource = "nuget.org";
private static readonly ImmutableArray<PackageSource> NugetPackageSources =
ImmutableArray.Create(new PackageSource(SymbolSearchUpdateEngine.NugetOrgSourceName, SymbolSearchUpdateEngine.NugetOrgSourceUri));
ImmutableArray.Create(new PackageSource(NugetOrgSource, "http://nuget.org/"));
protected override TestWorkspace CreateWorkspaceFromFile(string initialMarkup, TestParameters parameters)
{
......@@ -61,7 +63,7 @@ public async Task TestSearchPackageSingleName()
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(
SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace")));
await TestInRegularAndScriptAsync(
......@@ -92,7 +94,7 @@ public async Task TestSearchPackageMultipleNames()
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(
SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2")));
await TestInRegularAndScriptAsync(
......@@ -121,7 +123,7 @@ public async Task TestMissingIfPackageAlreadyInstalled()
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(
SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2")));
await TestMissingInRegularAndScriptAsync(
......@@ -147,7 +149,7 @@ public async Task TestOptionsOffered()
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(
SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NS1", "NS2")));
var data = new FixProviderData(installerServiceMock.Object, packageServiceMock.Object);
......@@ -191,7 +193,7 @@ public async Task TestInstallGetsCalledNoVersion()
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(
SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace")));
await TestInRegularAndScriptAsync(
......@@ -224,7 +226,7 @@ public async Task TestInstallGetsCalledWithVersion()
var packageServiceMock = new Mock<ISymbolSearchService>(MockBehavior.Strict);
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace")));
await TestInRegularAndScriptAsync(
......@@ -258,7 +260,7 @@ public async Task TestFailedInstallRollsBackFile()
var packageServiceMock = new Mock<ISymbolSearchService>(MockBehavior.Strict);
packageServiceMock.Setup(s => s.FindReferenceAssembliesWithTypeAsync("NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(Task.FromResult<IList<ReferenceAssemblyWithTypeResult>>(new List<ReferenceAssemblyWithTypeResult>()));
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "NuGetType", 0, It.IsAny<CancellationToken>()))
packageServiceMock.Setup(s => s.FindPackagesWithTypeAsync(NugetOrgSource, "NuGetType", 0, It.IsAny<CancellationToken>()))
.Returns(CreateSearchResult("NuGetPackage", "NuGetType", CreateNameParts("NuGetNamespace")));
await TestInRegularAndScriptAsync(
......
......@@ -7,10 +7,11 @@
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Editor.UnitTests.QuickInfo;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.QuickInfo;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
......@@ -6346,5 +6347,246 @@ void N()
}",
MainDescription("void M<T>() where T : notnull"));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableParameterThatIsMaybeNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
void N(string? s)
{
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.parameter}) string? s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_may_be_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableParameterThatIsNotNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
void N(string? s)
{
s = """";
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.parameter}) string? s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_is_not_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableFieldThatIsMaybeNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
string? s = null;
void N()
{
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.field}) string? X.s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_may_be_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableFieldThatIsNotNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
string? s = null;
void N()
{
s = """";
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.field}) string? X.s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_is_not_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullablePropertyThatIsMaybeNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
string? S { get; set; }
void N()
{
string s2 = $$S;
}
}",
MainDescription("string? X.S { get; set; }"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_may_be_null_here, "S")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullablePropertyThatIsNotNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
class X
{
string? S { get; set; }
void N()
{
S = """";
string s2 = $$S;
}
}",
MainDescription("string? X.S { get; set; }"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_is_not_null_here, "S")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableRangeVariableThatIsMaybeNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
IEnumerable<string?> enumerable;
foreach (var s in enumerable)
{
string s2 = $$s;
}
}
}",
MainDescription($"({FeaturesResources.local_variable}) string? s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_may_be_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableRangeVariableThatIsNotNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
IEnumerable<string> enumerable;
foreach (var s in enumerable)
{
string s2 = $$s;
}
}
}",
MainDescription($"({FeaturesResources.local_variable}) string s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_is_not_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableLocalThatIsMaybeNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
string? s = null;
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.local_variable}) string? s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_may_be_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableLocalThatIsNotNull()
{
await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
string? s = """";
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.local_variable}) string? s"),
NullabilityAnalysis(string.Format(CSharpFeaturesResources._0_is_not_null_here, "s")));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableNotShownPriorToLanguageVersion8()
{
await TestWithOptionsAsync(TestOptions.Regular7_3,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
string s = """";
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.local_variable}) string s"),
NullabilityAnalysis(""));
}
[Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)]
public async Task NullableNotShownWithoutFeatureFlag()
{
await TestWithOptionsAsync(TestOptions.Regular8,
@"#nullable enable
using System.Collections.Generic;
class X
{
void N()
{
string s = """";
string s2 = $$s;
}
}",
MainDescription($"({FeaturesResources.local_variable}) string s"),
NullabilityAnalysis(""));
}
}
}
......@@ -34,8 +34,7 @@ internal partial class SymbolSearchUpdateEngine
internal const string ChecksumAttributeName = "checksum";
internal const string UpToDateAttributeName = "upToDate";
internal const string TooOldAttributeName = "tooOld";
internal const string NugetOrgSourceName = "nuget.org";
internal const string NugetOrgSourceUri = "https://api.nuget.org/v3/index.json";
internal const string NugetOrgSource = "nuget.org";
public const string HostId = "RoslynNuGetSearch";
private const string MicrosoftAssemblyReferencesName = "MicrosoftAssemblyReferences";
......@@ -107,7 +106,7 @@ public Updater(SymbolSearchUpdateEngine service, string source, string localSett
internal async Task UpdateInBackgroundAsync()
{
// We only support this single source currently.
if (_source != NugetOrgSourceUri)
if (_source != NugetOrgSource)
{
return;
}
......
......@@ -160,7 +160,7 @@ internal partial class SymbolSearchUpdateEngine : ISymbolSearchUpdateEngine
string name, int arity, CancellationToken cancellationToken)
{
// Our reference assembly data is stored in the nuget.org DB.
if (!_sourceToDatabase.TryGetValue(NugetOrgSourceName, out var databaseWrapper))
if (!_sourceToDatabase.TryGetValue(NugetOrgSource, out var databaseWrapper))
{
// Don't have a database to search.
return SpecializedTasks.EmptyImmutableArray<ReferenceAssemblyWithTypeResult>();
......
......@@ -4,6 +4,7 @@
using System.Composition;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Options.Providers;
using Microsoft.CodeAnalysis.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Shared.Options
{
......@@ -84,7 +85,7 @@ internal static class FeatureOnOffOptions
storageLocations: new RoamingProfileStorageLocation("WindowManagement.Options.UseEnhancedColorsForManagedLanguages"));
/// <summary>
/// Feature to enable run-nullable-analysis in the compiler flags for all csharp projects.
/// Feature to enable <see cref="CompilerFeatureFlags.RunNullableAnalysis"/> in the compiler flags for all csharp projects.
/// 0 = default, which leaves the flag unset.
/// 1 = set to true
/// -1 = set to false
......
......@@ -97,6 +97,13 @@ internal Action<QuickInfoItem> WarningGlyph(Glyph expectedGlyph)
return item => AssertSection(expectedText, item.Sections, QuickInfoSectionKinds.AnonymousTypes, expectedClassifications);
}
protected Action<QuickInfoItem> NullabilityAnalysis(
string expectedText,
FormattedClassification[] expectedClassifications = null)
{
return item => AssertSection(expectedText, item.Sections, QuickInfoSectionKinds.NullabilityAnalysis, expectedClassifications);
}
protected Action<QuickInfoItem> NoTypeParameterMap
{
get
......
......@@ -155,6 +155,11 @@ public override bool IsVolatile
get { return false; }
}
public override FlowAnalysisAnnotations FlowAnalysisAnnotations
{
get { return FlowAnalysisAnnotations.None; }
}
public override ImmutableArray<Location> Locations
{
get { throw ExceptionUtilities.Unreachable; }
......
......@@ -69,6 +69,24 @@ internal class CSharpFeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; is not null here..
/// </summary>
internal static string _0_is_not_null_here {
get {
return ResourceManager.GetString("_0_is_not_null_here", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &apos;{0}&apos; may be null here..
/// </summary>
internal static string _0_may_be_null_here {
get {
return ResourceManager.GetString("_0_may_be_null_here", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add accessibility modifiers.
/// </summary>
......
......@@ -628,4 +628,10 @@
<value>Warning: Moving using directives may change code meaning.</value>
<comment>{Locked="using"} "using" is a C# keyword and should not be localized.</comment>
</data>
</root>
<data name="_0_is_not_null_here" xml:space="preserve">
<value>'{0}' is not null here.</value>
</data>
<data name="_0_may_be_null_here" xml:space="preserve">
<value>'{0}' may be null here.</value>
</data>
</root>
\ No newline at end of file
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Composition;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.QuickInfo;
using Microsoft.CodeAnalysis.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.QuickInfo
{
......@@ -42,5 +46,64 @@ protected override bool ShouldCheckPreviousToken(SyntaxToken token)
{
return !token.Parent.IsKind(SyntaxKind.XmlCrefAttribute);
}
protected override ImmutableArray<TaggedText> TryGetNullabilityAnalysis(Workspace workspace, SemanticModel semanticModel, SyntaxToken token, CancellationToken cancellationToken)
{
// Anything less than C# 8 we just won't show anything, even if the compiler could theoretically give analysis
var parseOptions = (CSharpParseOptions)token.SyntaxTree.Options;
if (parseOptions.LanguageVersion < LanguageVersion.CSharp8)
{
return default;
}
if (!parseOptions.Features.ContainsKey(CompilerFeatureFlags.RunNullableAnalysis))
{
return default;
}
var syntaxFacts = workspace.Services.GetLanguageServices(semanticModel.Language).GetRequiredService<ISyntaxFactsService>();
var bindableParent = syntaxFacts.GetBindableParent(token);
var symbolInfo = semanticModel.GetSymbolInfo(bindableParent, cancellationToken);
if (symbolInfo.Symbol == null || string.IsNullOrEmpty(symbolInfo.Symbol.Name))
{
return default;
}
// Although GetTypeInfo can return nullability for uses of all sorts of things, it's not always useful for quick info.
// For example, if you have a call to a method with a nullable return, the fact it can be null is already captured
// in the return type shown -- there's no flow analysis information there.
if (symbolInfo.Symbol.Kind != SymbolKind.Event &&
symbolInfo.Symbol.Kind != SymbolKind.Field &&
symbolInfo.Symbol.Kind != SymbolKind.Local &&
symbolInfo.Symbol.Kind != SymbolKind.Parameter &&
symbolInfo.Symbol.Kind != SymbolKind.Property &&
symbolInfo.Symbol.Kind != SymbolKind.RangeVariable)
{
return default;
}
var typeInfo = semanticModel.GetTypeInfo(bindableParent, cancellationToken);
string messageTemplate = null;
if (typeInfo.Nullability.FlowState == NullableFlowState.NotNull)
{
messageTemplate = CSharpFeaturesResources._0_is_not_null_here;
}
else if (typeInfo.Nullability.FlowState == NullableFlowState.MaybeNull)
{
messageTemplate = CSharpFeaturesResources._0_may_be_null_here;
}
if (messageTemplate != null)
{
return ImmutableArray.Create(new TaggedText(TextTags.Text, string.Format(messageTemplate, symbolInfo.Symbol.Name)));
}
else
{
return default;
}
}
}
}
......@@ -147,6 +147,16 @@
<target state="translated">Použít výraz switch</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">Příkaz if lze zjednodušit.</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Switch-Ausdruck verwenden</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">Die If-Anweisung kann vereinfacht werden.</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Usar la expresión "switch"</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">La instrucción "if" se puede simplificar</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Utiliser l'expression 'switch'</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">L'instruction 'if' peut être simplifiée</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Usa l'espressione 'switch'</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">L'istruzione 'If' può essere semplificata</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">'switch' 式を使用します</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">'if' ステートメントは簡素化できます</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">'switch' 식 사용</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">'if' 문을 간단하게 줄일 수 있습니다.</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Użyj wyrażenia „switch”</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">Instrukcja „if” może zostać uproszczona</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Usar a expressão 'switch'</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">A instrução 'if' pode ser simplificada</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">Использовать выражение switch</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">Оператор if можно упростить</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">'Switch' ifadesini kullan</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">'If' deyimi basitleştirilebilir</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">使用 "switch" 表达式</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">可简化“If”语句</target>
......
......@@ -147,6 +147,16 @@
<target state="translated">使用 'switch' 運算式</target>
<note />
</trans-unit>
<trans-unit id="_0_is_not_null_here">
<source>'{0}' is not null here.</source>
<target state="new">'{0}' is not null here.</target>
<note />
</trans-unit>
<trans-unit id="_0_may_be_null_here">
<source>'{0}' may be null here.</source>
<target state="new">'{0}' may be null here.</target>
<note />
</trans-unit>
<trans-unit id="if_statement_can_be_simplified">
<source>'if' statement can be simplified</source>
<target state="translated">'if' 陳述式可簡化</target>
......
......@@ -225,6 +225,12 @@ void AddSection(string kind, ImmutableArray<TaggedText> taggedParts)
usageTextBuilder.AddRange(awaitableUsageText);
}
var nullableAnalysis = TryGetNullabilityAnalysis(workspace, semanticModel, token, cancellationToken);
if (!nullableAnalysis.IsDefaultOrEmpty)
{
AddSection(QuickInfoSectionKinds.NullabilityAnalysis, nullableAnalysis);
}
if (supportedPlatforms != null)
{
usageTextBuilder.AddRange(supportedPlatforms.ToDisplayParts().ToTaggedText());
......@@ -298,6 +304,8 @@ void AddSection(string kind, ImmutableArray<TaggedText> taggedParts)
protected abstract bool GetBindableNodeForTokenIndicatingLambda(SyntaxToken token, out SyntaxNode found);
protected virtual ImmutableArray<TaggedText> TryGetNullabilityAnalysis(Workspace workspace, SemanticModel semanticModel, SyntaxToken token, CancellationToken cancellationToken) => default;
private async Task<(SemanticModel semanticModel, ImmutableArray<ISymbol> symbols)> BindTokenAsync(
Document document, SyntaxToken token, CancellationToken cancellationToken)
{
......
......@@ -16,5 +16,6 @@ public static class QuickInfoSectionKinds
public const string Exception = nameof(Exception);
public const string Text = nameof(Text);
public const string Captures = nameof(Captures);
internal const string NullabilityAnalysis = nameof(NullabilityAnalysis);
}
}
......@@ -7,6 +7,7 @@
using Microsoft.CodeAnalysis.Editor.Shared.Options;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Utilities;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
......@@ -205,11 +206,11 @@ private ParseOptions ComputeOptionsServiceParseOptions(ParseOptions parseOptions
if (useNullableReferenceAnalysisOption == -1)
{
parseOptions = parseOptions.WithFeatures(new[] { KeyValuePairUtil.Create("run-nullable-analysis", "false") });
parseOptions = parseOptions.WithFeatures(new[] { KeyValuePairUtil.Create(CompilerFeatureFlags.RunNullableAnalysis, "false") });
}
else if (useNullableReferenceAnalysisOption == 1)
{
parseOptions = parseOptions.WithFeatures(new[] { KeyValuePairUtil.Create("run-nullable-analysis", "true") });
parseOptions = parseOptions.WithFeatures(new[] { KeyValuePairUtil.Create(CompilerFeatureFlags.RunNullableAnalysis, "true") });
}
}
......
......@@ -78,7 +78,7 @@ protected override void StartWorking()
{
// Always pull down the nuget.org index. It contains the MS reference assembly index
// inside of it.
Task.Run(() => UpdateSourceInBackgroundAsync(SymbolSearchUpdateEngine.NugetOrgSourceUri));
Task.Run(() => UpdateSourceInBackgroundAsync(SymbolSearchUpdateEngine.NugetOrgSource));
}
private async Task<ISymbolSearchUpdateEngine> GetEngineAsync(CancellationToken cancellationToken)
......
......@@ -46,7 +46,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await service.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await service.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlService.Verify()
End Using
......@@ -77,7 +77,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await service.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await service.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlService.Verify()
End Using
......@@ -115,7 +115,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
serviceMock.Verify()
clientMock.Verify()
......@@ -159,7 +159,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
serviceMock.Verify()
clientMock.Verify()
......@@ -195,7 +195,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
serviceMock.Verify()
clientMock.Verify()
......@@ -244,7 +244,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -288,7 +288,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -336,7 +336,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -395,7 +395,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -441,7 +441,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -495,7 +495,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -555,7 +555,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......@@ -611,7 +611,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.SymbolSearch
reportAndSwallowException:=s_allButMoqExceptions,
updateCancellationToken:=cancellationTokenSource.Token)
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSourceName, "TestDirectory")
Await searchService.UpdateContinuouslyAsync(SymbolSearchUpdateEngine.NugetOrgSource, "TestDirectory")
ioMock.Verify()
remoteControlMock.Verify()
clientMock.Verify()
......
......@@ -33,7 +33,7 @@ public override async Task InitializeAsync()
VisualStudio.SolutionExplorer.AddProject(testProj, WellKnownProjectTemplates.ConsoleApplication, LanguageNames.VisualBasic);
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void UpdateActiveStatementLeafNode()
{
VisualStudio.Editor.SetText(@"
......@@ -64,7 +64,7 @@ End Module
VisualStudio.Debugger.CheckExpression("names(1)", "String", "\"bar\"");
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void AddTryCatchAroundActiveStatement()
{
VisualStudio.Editor.SetText(@"
......@@ -92,7 +92,7 @@ End Sub
VisualStudio.Editor.Verify.CurrentLineText("End Try");
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void EditLambdaExpression()
{
VisualStudio.Editor.SetText(@"
......@@ -123,7 +123,7 @@ End Sub
VisualStudio.ErrorList.Verify.NoBuildErrors();
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void EnCWhileDebuggingFromImmediateWindow()
{
VisualStudio.Editor.SetText(@"
......@@ -146,7 +146,6 @@ End Sub
VisualStudio.Debugger.ExecuteStatement("Module1.Main()");
}
[WpfFact]
private void SetupMultiProjectSolution()
{
var basicLibrary = new ProjectUtils.Project("BasicLibrary1");
......@@ -188,7 +187,7 @@ End Module
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void MultiProjectDebuggingWhereNotAllModulesAreLoaded()
{
SetupMultiProjectSolution();
......@@ -199,7 +198,7 @@ public void MultiProjectDebuggingWhereNotAllModulesAreLoaded()
VisualStudio.ErrorList.Verify.NoErrors();
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
[WorkItem(33829, "https://github.com/dotnet/roslyn/issues/33829")]
public void DocumentStateTrackingReadonlyInRunMode()
{
......@@ -250,7 +249,7 @@ End Module
VisualStudio.Editor.Verify.IsProjectItemDirty(expectedValue: false);
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void LocalsWindowUpdatesAfterLocalGetsItsTypeUpdatedDuringEnC()
{
VisualStudio.Editor.SetText(@"
......@@ -273,7 +272,7 @@ End Module
VisualStudio.LocalsWindow.Verify.CheckEntry("goo", "Single", "10");
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void LocalsWindowUpdatesCorrectlyDuringEnC()
{
VisualStudio.Editor.SetText(@"
......@@ -306,7 +305,7 @@ End Module
VisualStudio.LocalsWindow.Verify.CheckEntry("lLng", "Long", "444");
}
[WpfFact]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/36763")]
public void WatchWindowUpdatesCorrectlyDuringEnC()
{
VisualStudio.Editor.SetText(@"
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Microsoft.CodeAnalysis.Utilities
{
internal static class CompilerFeatureFlags
{
public const string RunNullableAnalysis = "run-nullable-analysis";
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册