diff --git a/.editorconfig b/.editorconfig index 8a2bc30b..e0a8f0cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -167,6 +167,15 @@ dotnet_diagnostic.SA1130.severity = silent # IDE1006: Naming Styles - StyleCop handles these for us dotnet_diagnostic.IDE1006.severity = none +dotnet_diagnostic.DOC100.severity = silent +dotnet_diagnostic.DOC104.severity = warning +dotnet_diagnostic.DOC105.severity = warning +dotnet_diagnostic.DOC106.severity = warning +dotnet_diagnostic.DOC107.severity = warning +dotnet_diagnostic.DOC108.severity = warning +dotnet_diagnostic.DOC200.severity = warning +dotnet_diagnostic.DOC202.severity = warning + dotnet_diagnostic.SA1600.severity = silent dotnet_diagnostic.SA1609.severity = none dotnet_diagnostic.SA1611.severity = none diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95a4d594..bb39635e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# StreamJsonRpc +# Contributing This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). @@ -10,16 +10,36 @@ with any additional questions or comments. We welcome 3rd party pull requests. For significant changes we strongly recommend opening an issue to start a design discussion first. -## Dev workflow +## Best practices -### Dependencies +* Use Windows PowerShell or [PowerShell Core][pwsh] (including on Linux/OSX) to run .ps1 scripts. + Some scripts set environment variables to help you, but they are only retained if you use PowerShell as your shell. -Get the .NET Core SDK and .NET Core runtimes that are required to build and test this repo by running `.\init.ps1 -InstallLocality Machine` from the root of the repo in a PowerShell window. +## Prerequisites -### Building +All dependencies can be installed by running the `init.ps1` script at the root of the repository +using Windows PowerShell or [PowerShell Core][pwsh] (on any OS). +Some dependencies installed by `init.ps1` may only be discoverable from the same command line environment the init script was run from due to environment variables, so be sure to launch Visual Studio or build the repo from that same environment. +Alternatively, run `init.ps1 -InstallLocality Machine` (which may require elevation) in order to install dependencies at machine-wide locations so Visual Studio and builds work everywhere. -Build using `dotnet build src` or `msbuild /restore src`. +The only prerequisite for building, testing, and deploying from this repository +is the [.NET SDK](https://get.dot.net/). +You should install the version specified in `global.json` or a later version within +the same major.minor.Bxx "hundreds" band. +For example if 2.2.300 is specified, you may install 2.2.300, 2.2.301, or 2.2.310 +while the 2.2.400 version would not be considered compatible by .NET SDK. +See [.NET Core Versioning](https://docs.microsoft.com/dotnet/core/versions/) for more information. -### Running tests +## Package restore -Run tests using `dotnet test src` or in Visual Studio with Test Explorer. +The easiest way to restore packages may be to run `init.ps1` which automatically authenticates +to the feeds that packages for this repo come from, if any. +`dotnet restore` or `nuget restore` also work but may require extra steps to authenticate to any applicable feeds. + +## Building + +This repository can be built on Windows, Linux, and OSX. + +Building, testing, and packing this repository can be done by using the standard dotnet CLI commands (e.g. `dotnet build`, `dotnet test`, `dotnet pack`, etc.). + +[pwsh]: https://docs.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-6 diff --git a/Directory.Build.props b/Directory.Build.props index d3562083..ed385f79 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -36,7 +36,6 @@ - @@ -44,6 +43,8 @@ + + diff --git a/Directory.Packages.props b/Directory.Packages.props index 24d1f484..caf82b76 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -34,6 +34,7 @@ + diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..0dc4b6a7 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/msrc/pgp-key-msrc). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/msrc/cvd). + + diff --git a/azure-pipelines/Archive-SourceCode.ps1 b/azure-pipelines/Archive-SourceCode.ps1 new file mode 100644 index 00000000..8f605a8e --- /dev/null +++ b/azure-pipelines/Archive-SourceCode.ps1 @@ -0,0 +1,220 @@ +#Requires -PSEdition Core -Version 7 +<# +.SYNOPSIS + Submits a source archival request for this repo. +.PARAMETER Requester + The alias for the user requesting this backup. +.PARAMETER ManagerAlias + The alias of the manager that owns the repo. +.PARAMETER TeamAlias + The alias of the team that owns the repo. +.PARAMETER BusinessGroupName + A human-readable title for your team or business group. +.PARAMETER ProductionType +.PARAMETER ReleaseType + The type of release being backed up. +.PARAMETER ReleaseDate + The date of the release of your software. Defaults to today. +.PARAMETER OwnerAlias + The alias of the owner. +.PARAMETER OS +.PARAMETER ProductLanguage + One or more languages. +.PARAMETER Notes + Any notes to record with the backup. +.PARAMETER FileCollection + One or more collections to archive. +.PARAMETER ProductName + The name of the product. This will default to the repository name. +.PARAMETER RepoUrl + The URL to the repository. This will default to the repository containing this script. +.PARAMETER BackupType + The kind of backup to be performed. +.PARAMETER ServerPath + The UNC path to the server to be backed up (if applicable). +.PARAMETER SourceCodeArchivalUri + The URI to POST the source code archival request to. + This value will typically come automatically by a variable group associated with your pipeline. + You can also look it up at https://dpsrequestforms.azurewebsites.net/#/help -> SCA Request Help -> SCA API Help -> Description +#> +[CmdletBinding(SupportsShouldProcess = $true, PositionalBinding = $false)] +param ( + [Parameter()] + [string]$Requester, + [Parameter(Mandatory = $true)] + [string]$ManagerAlias, + [Parameter(Mandatory = $true)] + [string]$TeamAlias, + [Parameter(Mandatory = $true)] + [string]$BusinessGroupName, + [Parameter()] + [string]$ProductionType = 'Visual Studio', + [Parameter()] + [string]$ReleaseType = 'RTW', + [Parameter()] + [DateTime]$ReleaseDate = [DateTime]::Today, + [Parameter()] + [string]$OwnerAlias, + [Parameter()] + [ValidateSet('64-Bit Win', '32-Bit Win', 'Linux', 'Mac', '64-Bit ARM', '32-Bit ARM')] + [string[]]$OS = @('64-Bit Win'), + [Parameter(Mandatory = $true)] + [ValidateSet('English', 'Chinese Simplified', 'Chinese Traditional', 'Czech', 'French', 'German', 'Italian', 'Japanese', 'Korean', 'Polish', 'Portuguese', 'Russian', 'Spanish', 'Turkish')] + [string[]]$ProductLanguage, + [Parameter()] + [string]$Notes = '', + [Parameter()] + [ValidateSet('Binaries', 'Localization', 'Source Code')] + [string[]]$FileCollection = @('Source Code'), + [Parameter()] + [string]$ProductName, + [Parameter()] + [Uri]$RepoUrl, + [Parameter()] + [ValidateSet('Server Path', 'Code Repo(Git URL/AzureDevOps)', 'Git', 'Azure Storage Account')] + [string]$BackupType = 'Code Repo(Git URL/AzureDevOps)', + [Parameter()] + [string]$ServerPath = '', + [Parameter()] + [Uri]$SourceCodeArchivalUri = $env:SOURCECODEARCHIVALURI +) + +function Invoke-Git() { + # Make sure we invoke git from within the repo. + Push-Location $PSScriptRoot + try { + return (git $args) + } + finally { + Pop-Location + } +} + +if (!$ProductName) { + if ($env:BUILD_REPOSITORY_NAME) { + Write-Verbose 'Using $env:BUILD_REPOSITORY_NAME for ProductName.' # single quotes are intentional so user sees the name of env var. + $ProductName = $env:BUILD_REPOSITORY_NAME + } + else { + $originUrl = [Uri](Invoke-Git remote get-url origin) + if ($originUrl) { + $lastPathSegment = $originUrl.Segments[$originUrl.Segments.Length - 1] + if ($lastPathSegment.EndsWith('.git')) { + $lastPathSegment = $lastPathSegment.Substring(0, $lastPathSegment.Length - '.git'.Length) + } + Write-Verbose 'Using origin remote URL to derive ProductName.' + $ProductName = $lastPathSegment + } + } + + if (!$ProductName) { + Write-Error "Unable to determine default value for -ProductName." + } +} + +if (!$OwnerAlias) { + if ($env:BUILD_REQUESTEDFOREMAIL) { + Write-Verbose 'Using $env:BUILD_REQUESTEDFOREMAIL and slicing to just the alias for OwnerAlias.' + $OwnerAlias = ($env:BUILD_REQUESTEDFOREMAIL -split '@')[0] + } + else { + Write-Verbose 'Using $env:USERNAME for OwnerAlias.' + $OwnerAlias = $env:USERNAME + } + if (!$OwnerAlias) { + Write-Error "Unable to determine default value for -OwnerAlias." + } +} + +if (!$Requester) { + if ($env:BUILD_REQUESTEDFOREMAIL) { + Write-Verbose 'Using $env:BUILD_REQUESTEDFOREMAIL and slicing to just the alias for Requester.' + $Requester = ($env:BUILD_REQUESTEDFOREMAIL -split '@')[0] + } + else { + Write-Verbose 'Using $env:USERNAME for Requester.' + $Requester = $env:USERNAME + } + if (!$Requester) { + Write-Error "Unable to determine default value for -Requester." + } +} + +if (!$RepoUrl) { + $RepoUrl = $env:BUILD_REPOSITORY_URI + if (!$RepoUrl) { + $originUrl = [Uri](Invoke-Git remote get-url origin) + if ($originUrl) { + Write-Verbose 'Using git origin remote url for GitURL.' + $RepoUrl = $originUrl + } + + if (!$RepoUrl) { + Write-Error "Unable to determine default value for -RepoUrl." + } + } +} + +Push-Location $PSScriptRoot +$versionsObj = & (& "$PSScriptRoot/Get-nbgv.ps1") get-version -f json | ConvertFrom-Json +Pop-Location + +$ReleaseDateString = $ReleaseDate.ToShortDateString() +$Version = $versionsObj.Version + +$BackupSize = Get-ChildItem $PSScriptRoot\..\.git -Recurse -File | Measure-Object -Property Length -Sum +$DataSizeMB = [int]($BackupSize.Sum / 1mb) +$FileCount = $BackupSize.Count + +$Request = @{ + "Requester" = $Requester + "Manager" = $ManagerAlias + "TeamAlias" = $TeamAlias + "AdditionalContacts" = $AdditionalContacts + "BusinessGroupName" = $BusinessGroupName + "ProductName" = $ProductName + "Version" = $Version + "ProductionType" = $ProductionType + "ReleaseType" = $ReleaseType + "ReleaseDateString" = $ReleaseDateString + "OS" = [string]::Join(',', $OS) + "ProductLanguage" = [string]::Join(',', $ProductLanguage) + "FileCollection" = [string]::Join(',', $FileCollection) + "OwnerAlias" = $OwnerAlias + "Notes" = $Notes.Trim() + "CustomerProvidedDataSizeMB" = $DataSizeMB + "CustomerProvidedFileCount" = $FileCount + "BackupType" = $BackupType + "ServerPath" = $ServerPath + "AzureStorageAccount" = $AzureStorageAccount + "AzureStorageContainer" = $AzureStorageContainer + "GitURL" = $RepoUrl +} + +$RequestJson = ConvertTo-Json $Request +Write-Host "SCA request:`n$RequestJson" + +if ($PSCmdlet.ShouldProcess('source archival request', 'post')) { + if (!$SourceCodeArchivalUri) { + Write-Error "Unable to post request without -SourceCodeArchivalUri parameter." + exit 1 + } + + [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + + $Response = Invoke-WebRequest -Uri $SourceCodeArchivalUri -Method POST -Body $RequestJson -ContentType "application/json" -UseBasicParsing -SkipHttpErrorCheck + Write-Host "Status Code : " -NoNewline + $responseContent = ConvertFrom-Json ($Response.Content) + if ($Response.StatusCode -eq 200) { + Write-Host $Response.StatusCode -ForegroundColor Green + Write-Host "Ticket ID : " -NoNewline + Write-Host $responseContent + } + else { + $responseContent = ConvertFrom-Json $Response.Content + Write-Host $Response.StatusCode -ForegroundColor Red + Write-Host "Message : $($responseContent.message)" + } +} elseif ($SourceCodeArchivalUri) { + Write-Host "Would have posted to $SourceCodeArchivalUri" +} diff --git a/azure-pipelines/Get-InsertionPRId.ps1 b/azure-pipelines/Get-InsertionPRId.ps1 new file mode 100644 index 00000000..62cb30cd --- /dev/null +++ b/azure-pipelines/Get-InsertionPRId.ps1 @@ -0,0 +1,26 @@ +<# +.SYNOPSIS + Look up the pull request URL of the insertion PR. +#> +$stagingFolder = $env:BUILD_STAGINGDIRECTORY +if (!$stagingFolder) { + $stagingFolder = $env:SYSTEM_DEFAULTWORKINGDIRECTORY + if (!$stagingFolder) { + Write-Error "This script must be run in an Azure Pipeline." + exit 1 + } +} +$markdownFolder = Join-Path $stagingFolder (Join-Path 'MicroBuild' 'Output') +$markdownFile = Join-Path $markdownFolder 'PullRequestUrl.md' +if (!(Test-Path $markdownFile)) { + Write-Error "This script should be run after the MicroBuildInsertVsPayload task." + exit 2 +} + +$insertionPRUrl = Get-Content $markdownFile +if (!($insertionPRUrl -match 'https:.+?/pullrequest/(\d+)')) { + Write-Error "Failed to parse pull request URL: $insertionPRUrl" + exit 3 +} + +$Matches[1] diff --git a/azure-pipelines/Get-SymbolFiles.ps1 b/azure-pipelines/Get-SymbolFiles.ps1 index 9183c340..0ce229fc 100644 --- a/azure-pipelines/Get-SymbolFiles.ps1 +++ b/azure-pipelines/Get-SymbolFiles.ps1 @@ -18,7 +18,7 @@ Write-Progress -Activity $ActivityName -CurrentOperation "Discovery PDB files" $PDBs = Get-ChildItem -rec "$Path/*.pdb" # Filter PDBs to product OR test related. -$testregex = "unittest|tests" +$testregex = "unittest|tests|\.test\." Write-Progress -Activity $ActivityName -CurrentOperation "De-duplicating symbols" $PDBsByHash = @{} diff --git a/azure-pipelines/Install-NuGetPackage.ps1 b/azure-pipelines/Install-NuGetPackage.ps1 index 13967233..cdac7308 100644 --- a/azure-pipelines/Install-NuGetPackage.ps1 +++ b/azure-pipelines/Install-NuGetPackage.ps1 @@ -11,6 +11,8 @@ The directory to install the package to. By default, it uses the Packages folder at the root of the repo. .PARAMETER ConfigFile The nuget.config file to use. By default, it uses :/nuget.config. +.OUTPUTS + System.String. The path to the installed package. #> [CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Low')] Param( @@ -46,6 +48,7 @@ try { if ($p.ExitCode -ne 0) { throw } } + # Provide the path to the installed package directory to our caller. Write-Output (Get-ChildItem "$PackagesDir\$PackageId.*")[0].FullName } finally { Pop-Location diff --git a/azure-pipelines/Merge-CodeCoverage.ps1 b/azure-pipelines/Merge-CodeCoverage.ps1 index 91ab67ab..9fe925cf 100644 --- a/azure-pipelines/Merge-CodeCoverage.ps1 +++ b/azure-pipelines/Merge-CodeCoverage.ps1 @@ -16,13 +16,13 @@ Param( [string[]]$Path, [ValidateSet('Badges', 'Clover', 'Cobertura', 'CsvSummary', 'Html', 'Html_Dark', 'Html_Light', 'HtmlChart', 'HtmlInline', 'HtmlInline_AzurePipelines', 'HtmlInline_AzurePipelines_Dark', 'HtmlInline_AzurePipelines_Light', 'HtmlSummary', 'JsonSummary', 'Latex', 'LatexSummary', 'lcov', 'MarkdownSummary', 'MHtml', 'PngChart', 'SonarQube', 'TeamCitySummary', 'TextSummary', 'Xml', 'XmlSummary')] [string]$Format='Cobertura', - [string]$OutputDir=("$PSScriptRoot/../coveragereport") + [string]$OutputFile=("$PSScriptRoot/../coveragereport/merged.cobertura.xml") ) $RepoRoot = [string](Resolve-Path $PSScriptRoot/..) -if (!(Test-Path $RepoRoot/obj/reportgenerator*)) { - dotnet tool install --tool-path $RepoRoot/obj dotnet-reportgenerator-globaltool --version 5.1.9 --configfile $PSScriptRoot/justnugetorg.nuget.config +if (!(Test-Path $RepoRoot/obj/dotnet-coverage*)) { + dotnet tool install --tool-path $RepoRoot/obj dotnet-coverage --version 17.4.3 --configfile $PSScriptRoot/justnugetorg.nuget.config } Write-Verbose "Searching $Path for *.cobertura.xml files" @@ -39,8 +39,13 @@ if ($reports) { $xml.Save($_) } - $Inputs = [string]::join(';', ($reports |% { Resolve-Path -relative $_.FullName })) - & "$RepoRoot/obj/reportgenerator" -reports:"$Inputs" -targetdir:$OutputDir -reporttypes:$Format + $Inputs = $reports |% { Resolve-Path -relative $_.FullName } + + if (Split-Path $OutputFile) { + New-Item -Type Directory -Path (Split-Path $OutputFile) | Out-Null + } + + & "$RepoRoot/obj/dotnet-coverage" merge $Inputs -o $OutputFile -f cobertura } else { Write-Error "No reports found to merge." } diff --git a/azure-pipelines/PostPRMessage.ps1 b/azure-pipelines/PostPRMessage.ps1 new file mode 100644 index 00000000..4a2b7886 --- /dev/null +++ b/azure-pipelines/PostPRMessage.ps1 @@ -0,0 +1,57 @@ +[CmdletBinding(SupportsShouldProcess = $true)] +param( + [Parameter(Mandatory=$true)] + $AccessToken, + [Parameter(Mandatory=$true)] + $Markdown, + [ValidateSet('Active','ByDesign','Closed','Fixed','Pending','Unknown','WontFix')] + $CommentState='Active' +) + +# See https://docs.microsoft.com/en-us/dotnet/api/microsoft.teamfoundation.sourcecontrol.webapi.commentthreadstatus?view=azure-devops-dotnet +if ($CommentState -eq 'Active') { + $StatusCode = 1 +} elseif ($CommentState -eq 'ByDesign') { + $StatusCode = 5 +} elseif ($CommentState -eq 'Closed') { + $StatusCode = 4 +} elseif ($CommentState -eq 'Fixed') { + $StatusCode = 2 +} elseif ($CommentState -eq 'Pending') { + $StatusCode = 6 +} elseif ($CommentState -eq 'Unknown') { + $StatusCode = 0 +} elseif ($CommentState -eq 'WontFix') { + $StatusCode = 3 +} + +# Build the JSON body up +$body = ConvertTo-Json @{ + comments = @(@{ + parentCommentId = 0 + content = $Markdown + commentType = 1 + }) + status = $StatusCode +} + +Write-Verbose "Posting JSON payload: `n$Body" + +# Post the message to the Pull Request +# https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull%20request%20threads?view=azure-devops-rest-5.1 +$url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/git/repositories/$($env:BUILD_REPOSITORY_NAME)/pullRequests/$($env:SYSTEM_PULLREQUEST_PULLREQUESTID)/threads?api-version=5.1" +if ($PSCmdlet.ShouldProcess($url, 'Post comment via REST call')) { + try { + if (!$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI) { + Write-Error "Posting to the pull request requires that the script is running in an Azure Pipelines context." + exit 1 + } + Write-Host "Posting PR comment to: $url" + Invoke-RestMethod -Uri $url -Method POST -Headers @{Authorization = "Bearer $AccessToken"} -Body $Body -ContentType application/json + } + catch { + Write-Error $_ + Write-Error $_.Exception.Message + exit 2 + } +} diff --git a/azure-pipelines/archive-sourcecode.yml b/azure-pipelines/archive-sourcecode.yml new file mode 100644 index 00000000..2f00a00c --- /dev/null +++ b/azure-pipelines/archive-sourcecode.yml @@ -0,0 +1,51 @@ +trigger: none # We only want to trigger manually or based on resources +pr: none + +# Source archival requirements come from a compliance tenet. Review a sample task here: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1550985 +# Source code should be archived within 30 days of the release date, and at least every quarter if your product is releasing more than once every 6 months. +# If your sources on GitHub are public open source project, then using GitHub Public Archive is sufficient. +schedules: +- cron: "13 13 13 */3 *" # Every three months + displayName: Periodic source archival + branches: + include: + - main + +parameters: +- name: notes + displayName: Notes to include in the SCA request + type: string + default: ' ' # optional parameters require a non-empty default. +- name: whatif + displayName: Only simulate the request + type: boolean + +variables: +- group: VS Core team # Expected to provide ManagerAlias, SourceCodeArchivalUri + +pool: + name: AzurePipelines-EO + vmImage: AzurePipelinesUbuntu20.04compliant + +steps: +- checkout: self + clean: true + fetchDepth: 0 +- powershell: tools/Install-DotNetSdk.ps1 + displayName: ⚙ Install .NET SDK +- powershell: azure-pipelines/variables/_pipelines.ps1 + failOnStderr: true + displayName: ⚙ Set pipeline variables based on source +- powershell: > + $TeamAlias = '$(TeamEmail)'.Substring(0, '$(TeamEmail)'.IndexOf('@')) + + azure-pipelines/Archive-SourceCode.ps1 + -ManagerAlias '$(ManagerAlias)' + -TeamAlias $TeamAlias + -BusinessGroupName '$(BusinessGroupName)' + -ProductName '$(SymbolsFeatureName)' + -ProductLanguage English + -Notes '${{ parameters.notes }}' + -Verbose + -WhatIf:$${{ parameters.whatif }} + displayName: 🗃️ Submit archival request diff --git a/azure-pipelines/build.yml b/azure-pipelines/build.yml index a5fe1a07..8ec598b2 100644 --- a/azure-pipelines/build.yml +++ b/azure-pipelines/build.yml @@ -24,9 +24,10 @@ jobs: variables: - ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: # https://dev.azure.com/devdiv/DevDiv/_wiki/wikis/DevDiv.wiki/25351/APIScan-step-by-step-guide-to-setting-up-a-Pipeline - - group: VSExtensibility-APIScan + - group: VSExtensibility-APIScan # Expected to provide ApiScanClientId, ApiScanSecret, ApiScanTenant steps: - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - ${{ if eq(variables['Build.Reason'], 'Schedule') }}: @@ -64,6 +65,7 @@ jobs: vmImage: Ubuntu 20.04 steps: - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - template: install-dependencies.yml - template: dotnet.yml @@ -73,9 +75,10 @@ jobs: - job: macOS condition: ${{ parameters.includeMacOS }} pool: - vmImage: macOS-10.15 + vmImage: macOS-12 steps: - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - template: install-dependencies.yml - template: dotnet.yml @@ -91,6 +94,7 @@ jobs: condition: succeededOrFailed() steps: - checkout: self + fetchDepth: 0 # avoid shallow clone so nbgv can do its work. clean: true - template: install-dependencies.yml parameters: diff --git a/azure-pipelines/dotnet.yml b/azure-pipelines/dotnet.yml index 8d8de9c5..a4f993cf 100644 --- a/azure-pipelines/dotnet.yml +++ b/azure-pipelines/dotnet.yml @@ -35,11 +35,11 @@ steps: displayName: 📢 Publish artifacts condition: succeededOrFailed() -- powershell: | - $ArtifactStagingFolder = & "azure-pipelines/Get-ArtifactsStagingDirectory.ps1" - $CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)" - azure-pipelines/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)Host,$(BuildConfiguration)" - displayName: 📢 Publish code coverage results to codecov.io - condition: ne(variables['codecov_token'], '') - timeoutInMinutes: 3 - continueOnError: true +- ${{ if and(ne(variables['codecov_token'], ''), parameters.RunTests) }}: + - powershell: | + $ArtifactStagingFolder = & "azure-pipelines/Get-ArtifactsStagingDirectory.ps1" + $CoverageResultsFolder = Join-Path $ArtifactStagingFolder "coverageResults-$(Agent.JobName)" + azure-pipelines/publish-CodeCov.ps1 -CodeCovToken "$(codecov_token)" -PathToCodeCoverage "$CoverageResultsFolder" -Name "$(Agent.JobName) Coverage Results" -Flags "$(Agent.JobName)Host,$(BuildConfiguration)" + displayName: 📢 Publish code coverage results to codecov.io + timeoutInMinutes: 3 + continueOnError: true diff --git a/azure-pipelines/install-dependencies.yml b/azure-pipelines/install-dependencies.yml index 3993f104..cdfd2ed4 100644 --- a/azure-pipelines/install-dependencies.yml +++ b/azure-pipelines/install-dependencies.yml @@ -3,10 +3,12 @@ parameters: steps: -- task: NuGetAuthenticate@0 - displayName: 🔏 Authenticate NuGet feeds - inputs: - forceReinstallCredentialProvider: true +- ${{ if eq(variables['system.collectionId'], '011b8bdf-6d56-4f87-be0d-0092136884d9') }}: + - task: NuGetAuthenticate@1 + displayName: 🔏 Authenticate NuGet feeds + inputs: + nuGetServiceConnections: azure-public/msft_consumption + forceReinstallCredentialProvider: true - powershell: | $AccessToken = '$(System.AccessToken)' # Avoid specifying the access token directly on the init.ps1 command line to avoid it showing up in errors diff --git a/azure-pipelines/official.yml b/azure-pipelines/official.yml index 242e50e2..94bb6f78 100644 --- a/azure-pipelines/official.yml +++ b/azure-pipelines/official.yml @@ -68,58 +68,4 @@ stages: includeMacOS: ${{ parameters.includeMacOS }} RunTests: ${{ parameters.RunTests }} -- stage: symbol_archive - displayName: Symbol archival - condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real')) - jobs: - - job: archive - pool: VSEng-ReleasePool-1ES - steps: - - checkout: none - - download: current - artifact: Variables-Windows - displayName: Download Variables-Windows artifact - - task: PowerShell@2 - displayName: Set VSTS variables based on artifacts - inputs: - targetType: filePath - filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1 - - download: current - artifact: symbols-legacy - displayName: Download symbols-legacy artifact - - task: MicroBuildArchiveSymbols@1 - displayName: Archive symbols to Symweb - inputs: - SymbolsFeatureName: $(SymbolsFeatureName) - SymbolsSymwebProject: VS - SymbolsUncPath: \\cpvsbuild\drops\$(TeamName)\$(Build.DefinitionName)\$(Build.SourceBranchName)\$(Build.BuildId)\Symbols.Archival - SymbolsEmailContacts: vsidemicrobuild - SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy - - task: MicroBuildCleanup@1 - displayName: Send Telemetry - -- stage: azure_public_vssdk_feed - displayName: azure-public/vssdk feed - condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real')) - jobs: - - job: push - pool: - name: AzurePipelines-EO - vmImage: AzurePipelinesUbuntu20.04compliant - steps: - - checkout: none - - download: current - artifact: deployables-Windows - displayName: Download deployables-Windows artifact - - task: UseDotNet@2 - displayName: Install .NET SDK - inputs: - packageType: sdk - version: 6.x - - task: NuGetAuthenticate@0 - displayName: Authenticate NuGet feeds - inputs: - nuGetServiceConnections: azure-public/vssdk - forceReinstallCredentialProvider: true - - script: dotnet nuget push $(Pipeline.Workspace)/deployables-Windows/NuGet/*.nupkg -s https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json --api-key azdo --skip-duplicate - displayName: Push nuget packages +- template: prepare-insertion-stages.yml diff --git a/azure-pipelines/prepare-insertion-stages.yml b/azure-pipelines/prepare-insertion-stages.yml new file mode 100644 index 00000000..85b5fc69 --- /dev/null +++ b/azure-pipelines/prepare-insertion-stages.yml @@ -0,0 +1,56 @@ +stages: +- stage: symbol_archive + displayName: Symbol archival + condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real')) + jobs: + - job: archive + pool: VSEng-ReleasePool-1ES + steps: + - checkout: none + - download: current + artifact: Variables-Windows + displayName: Download Variables-Windows artifact + - task: PowerShell@2 + displayName: Set pipeline variables based on artifacts + inputs: + targetType: filePath + filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1 + - download: current + artifact: symbols-legacy + displayName: Download symbols-legacy artifact + - task: MicroBuildArchiveSymbols@1 + displayName: Archive symbols to Symweb + inputs: + SymbolsFeatureName: $(SymbolsFeatureName) + SymbolsSymwebProject: VS + SymbolsUncPath: \\cpvsbuild\drops\$(TeamName)\$(Build.DefinitionName)\$(Build.SourceBranchName)\$(Build.BuildId)\Symbols.Archival + SymbolsEmailContacts: vsidemicrobuild + SymbolsAgentPath: $(Pipeline.Workspace)/symbols-legacy + - task: MicroBuildCleanup@1 + displayName: Send Telemetry + +- stage: azure_public_vssdk_feed + displayName: azure-public/vssdk feed + condition: and(succeeded(), eq(dependencies.Build.outputs['Windows.SetPipelineVariables.SignType'], 'Real')) + jobs: + - job: push + pool: + name: AzurePipelines-EO + vmImage: AzurePipelinesUbuntu20.04compliant + steps: + - checkout: none + - download: current + artifact: deployables-Windows + displayName: Download deployables-Windows artifact + - task: UseDotNet@2 + displayName: Install .NET SDK + inputs: + packageType: sdk + version: 6.x + - task: NuGetAuthenticate@1 + displayName: Authenticate NuGet feeds + inputs: + nuGetServiceConnections: azure-public/vssdk + forceReinstallCredentialProvider: true + - script: dotnet nuget push $(Pipeline.Workspace)/deployables-Windows/NuGet/*.nupkg -s https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json --api-key azdo --skip-duplicate + displayName: Push nuget packages diff --git a/azure-pipelines/publish-codecoverage.yml b/azure-pipelines/publish-codecoverage.yml index 11de8ffa..fbb6a39a 100644 --- a/azure-pipelines/publish-codecoverage.yml +++ b/azure-pipelines/publish-codecoverage.yml @@ -15,11 +15,11 @@ steps: displayName: 🔻 Download macOS code coverage results continueOnError: true condition: and(succeeded(), ${{ parameters.includeMacOS }}) -- powershell: azure-pipelines/Merge-CodeCoverage.ps1 -Path '$(Pipeline.Workspace)' -OutputDir coveragereport -Format Cobertura -Verbose +- powershell: azure-pipelines/Merge-CodeCoverage.ps1 -Path '$(Pipeline.Workspace)' -OutputFile coveragereport/merged.cobertura.xml -Format Cobertura -Verbose displayName: ⚙ Merge coverage - task: PublishCodeCoverageResults@1 displayName: 📢 Publish code coverage results to Azure DevOps inputs: codeCoverageTool: cobertura - summaryFileLocation: coveragereport/Cobertura.xml + summaryFileLocation: coveragereport/merged.cobertura.xml failIfCoverageEmpty: true diff --git a/azure-pipelines/release.yml b/azure-pipelines/release.yml index b8427b06..de4228dc 100644 --- a/azure-pipelines/release.yml +++ b/azure-pipelines/release.yml @@ -10,7 +10,7 @@ resources: - auto-release variables: -- group: VS SDK feeds +- group: VS SDK feeds # Expected to provide NuGetOrgApiKey jobs: - job: release diff --git a/azure-pipelines/variables/BusinessGroupName.ps1 b/azure-pipelines/variables/BusinessGroupName.ps1 new file mode 100644 index 00000000..00824266 --- /dev/null +++ b/azure-pipelines/variables/BusinessGroupName.ps1 @@ -0,0 +1 @@ +'Visual Studio - VS Core' diff --git a/azure-pipelines/variables/InsertReviewers.ps1 b/azure-pipelines/variables/InsertReviewers.ps1 index fcff08d9..d58944ea 100644 --- a/azure-pipelines/variables/InsertReviewers.ps1 +++ b/azure-pipelines/variables/InsertReviewers.ps1 @@ -1 +1,9 @@ -'VS Core - Extensibility, Andrew Arnott' +# This is a list of AzDO account names or email addresses. +# Add your team DL and/or whoever should be notified of insertion PRs. +$contacts = ,$env:BUILD_REQUESTEDFOREMAIL +$contacts += 'VS Core - Extensibility','Andrew Arnott' + +$contacts = $contacts |? { $_ } +if ($contacts) { + [string]::Join(',', $contacts) +} diff --git a/azure-pipelines/vs-insertion.yml b/azure-pipelines/vs-insertion.yml index 0352d1ec..83e811f4 100644 --- a/azure-pipelines/vs-insertion.yml +++ b/azure-pipelines/vs-insertion.yml @@ -20,15 +20,15 @@ jobs: - checkout: none - powershell: Write-Host "##vso[build.updatebuildnumber]$(resources.pipeline.CI.runName)" displayName: Set pipeline name - - task: NuGetAuthenticate@0 - displayName: Authenticate NuGet feeds - inputs: - forceReinstallCredentialProvider: true - task: UseDotNet@2 displayName: Install .NET SDK inputs: packageType: sdk version: 6.x + - task: NuGetAuthenticate@1 + displayName: Authenticate NuGet feeds + inputs: + forceReinstallCredentialProvider: true - template: release-deployment-prep.yml - download: CI artifact: VSInsertion-Windows diff --git a/azure-pipelines/vs-validation.yml b/azure-pipelines/vs-validation.yml new file mode 100644 index 00000000..3cbc196e --- /dev/null +++ b/azure-pipelines/vs-validation.yml @@ -0,0 +1,84 @@ +# This is a top-level pipeline file, which is designed to be added as an optional PR build policy +# so that a VS insertion and all the validation that entails can be done before ever merging the PR +# in its original repo. + +trigger: none # We only want to trigger manually or based on resources +pr: none + +stages: +- stage: Build + variables: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + NUGET_PACKAGES: $(Agent.TempDirectory)/.nuget/packages + SignTypeSelection: Real + BuildConfiguration: Release + ValidationBuild: true + + jobs: + - template: build.yml + parameters: + EnableCompliance: false + EnableAPIScan: false + windowsPool: VSEngSS-MicroBuild2022-1ES + includeMacOS: false + RunTests: false + +- template: prepare-insertion-stages.yml + +- stage: insertion + displayName: VS insertion + jobs: + - job: insertion + displayName: VS insertion + pool: VSEngSS-MicroBuild2022-1ES + steps: + - checkout: self + clean: true + fetchDepth: 1 + - task: UseDotNet@2 + displayName: Install .NET SDK + inputs: + packageType: sdk + version: 6.x + - task: NuGetAuthenticate@1 + displayName: Authenticate NuGet feeds + inputs: + forceReinstallCredentialProvider: true + - download: current + artifact: Variables-Windows + displayName: Download Variables-Windows artifact + - task: PowerShell@2 + displayName: Set pipeline variables based on artifacts + inputs: + targetType: filePath + filePath: $(Pipeline.Workspace)/Variables-Windows/_pipelines.ps1 + - download: current + artifact: VSInsertion-Windows + displayName: Download VSInsertion-Windows artifact + - script: dotnet nuget push VSInsertion-windows\*.nupkg -s https://pkgs.dev.azure.com/devdiv/_packaging/VS/nuget/v3/index.json -k azdo --skip-duplicate + displayName: Push CoreXT packages to VS feed + workingDirectory: $(Pipeline.Workspace) + - task: MicroBuildInsertVsPayload@4 + displayName: Insert VS Payload + inputs: + TeamName: $(TeamName) + TeamEmail: $(TeamEmail) + InsertionPayloadName: $(Build.Repository.Name) VALIDATION BUILD $(Build.BuildNumber) ($(Build.SourceBranch)) + InsertionDescription: | + This PR is for **validation purposes only** for !$(System.PullRequest.PullRequestId). **Do not complete**. + CustomScriptExecutionCommand: src/VSSDK/NuGet/AllowUnstablePackages.ps1 + InsertionBuildPolicy: Request Perf DDRITs + InsertionReviewers: $(Build.RequestedForEmail) + AutoCompletePR: false + - powershell: | + $insertionPRId = azure-pipelines/Get-InsertionPRId.ps1 + $Markdown = @" + Validation insertion pull request created: !$insertionPRId + Please check status there before proceeding to merge this PR. + Remember to Abandon and (if allowed) to Delete Source Branch on that insertion PR when validation is complete. + "@ + azure-pipelines/PostPRMessage.ps1 -AccessToken '$(System.AccessToken)' -Markdown $Markdown -Verbose + displayName: Comment on pull request + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) + - task: MicroBuildCleanup@1 + displayName: Send Telemetry diff --git a/src/StreamJsonRpc/AwaitExtensions.cs b/src/StreamJsonRpc/AwaitExtensions.cs index 66e6d77c..0554be21 100644 --- a/src/StreamJsonRpc/AwaitExtensions.cs +++ b/src/StreamJsonRpc/AwaitExtensions.cs @@ -51,7 +51,7 @@ internal SynchronizationContextAwaiter(SynchronizationContext synchronizationCon /// Gets a value indicating whether the caller is already on the desired context. /// /// - /// We always return false because we use this to invoke server methods and we *always* want to + /// We always return because we use this to invoke server methods and we *always* want to /// yield before invoking them, even if this is the default SynchronizationContext that the caller is on. /// public bool IsCompleted => false; diff --git a/src/StreamJsonRpc/Exceptions/RpcArgumentDeserializationException.cs b/src/StreamJsonRpc/Exceptions/RpcArgumentDeserializationException.cs index 919f5df2..394f0be3 100644 --- a/src/StreamJsonRpc/Exceptions/RpcArgumentDeserializationException.cs +++ b/src/StreamJsonRpc/Exceptions/RpcArgumentDeserializationException.cs @@ -69,7 +69,7 @@ protected RpcArgumentDeserializationException(SerializationInfo info, StreamingC /// Gets the name of the argument from the JSON-RPC request that failed to deserialize, if available. /// /// - /// This value will be null when the JSON-RPC request uses positional arguments. + /// This value will be when the JSON-RPC request uses positional arguments. /// public string? ArgumentName { get; private set; } @@ -77,7 +77,7 @@ protected RpcArgumentDeserializationException(SerializationInfo info, StreamingC /// Gets the 0-based index of the argument from the JSON-RPC request that failed to deserialize, if available. /// /// - /// This value will be null when the JSON-RPC request uses named arguments. + /// This value will be when the JSON-RPC request uses named arguments. /// public int? ArgumentPosition { get; private set; } diff --git a/src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs b/src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs index 4c1fdf63..fc90f287 100644 --- a/src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs +++ b/src/StreamJsonRpc/HeaderDelimitedMessageHandler.cs @@ -282,7 +282,7 @@ unsafe int WriteHeaderText(string value, Span memory) /// Extracts the content encoding from a Content-Type header. /// /// The value of the Content-Type header. - /// The Encoding, if the header specified one; otherwise null. + /// The Encoding, if the header specified one; otherwise . [MethodImpl(MethodImplOptions.NoInlining)] // keep System.Net.Http dependency in its own method to avoid loading it if there is no such header. private static unsafe Encoding? ParseEncodingFromContentTypeHeader(ReadOnlySequence contentTypeValue) { diff --git a/src/StreamJsonRpc/IJsonRpcMessageHandler.cs b/src/StreamJsonRpc/IJsonRpcMessageHandler.cs index 5d398b01..f2892014 100644 --- a/src/StreamJsonRpc/IJsonRpcMessageHandler.cs +++ b/src/StreamJsonRpc/IJsonRpcMessageHandler.cs @@ -29,8 +29,8 @@ public interface IJsonRpcMessageHandler /// Reads a distinct and complete message from the transport, waiting for one if necessary. /// /// A token to cancel the read request. - /// The received message, or null if the underlying transport ends before beginning another message. - /// Thrown when returns false. + /// The received message, or if the underlying transport ends before beginning another message. + /// Thrown when returns . /// Thrown if the transport ends while reading a message. /// Thrown if is canceled before a new message is received. /// @@ -45,7 +45,7 @@ public interface IJsonRpcMessageHandler /// The message to write. /// A token to cancel the write request. /// A task that represents the asynchronous operation. - /// Thrown when returns false. + /// Thrown when returns . /// Thrown if is canceled before message transmission begins. /// /// Implementations should expect this method to be invoked concurrently diff --git a/src/StreamJsonRpc/JsonMessageFormatter.cs b/src/StreamJsonRpc/JsonMessageFormatter.cs index 7660e4a4..2a242e5b 100644 --- a/src/StreamJsonRpc/JsonMessageFormatter.cs +++ b/src/StreamJsonRpc/JsonMessageFormatter.cs @@ -507,7 +507,7 @@ public void Dispose() /// /// Disposes managed and native resources held by this instance. /// - /// true if being disposed; false if being finalized. + /// if being disposed; if being finalized. protected virtual void Dispose(bool disposing) { this.duplexPipeTracker?.Dispose(); diff --git a/src/StreamJsonRpc/JsonRpc.cs b/src/StreamJsonRpc/JsonRpc.cs index 193ab5d4..761441b0 100644 --- a/src/StreamJsonRpc/JsonRpc.cs +++ b/src/StreamJsonRpc/JsonRpc.cs @@ -466,14 +466,14 @@ public Task Completion /// can be changed after or /// has been called. /// - /// The default is false. + /// The default is . /// /// By default, all configuration such as target objects and target methods must be set /// before listening starts to avoid a race condition whereby we receive a method invocation /// message before we have wired up a handler for it and must reject the call. /// But in some advanced scenarios, it may be necessary to add target methods after listening /// has started (e.g. in response to an invocation that enables additional functionality), - /// in which case setting this property to true is appropriate. + /// in which case setting this property to is appropriate. /// public bool AllowModificationWhileListening { get; set; } @@ -702,7 +702,7 @@ public static T Attach(IJsonRpcMessageHandler handler) /// /// The interface that describes the functions available on the remote end. /// The message handler to use. - /// A set of customizations for how the client proxy is wired up. If null, default options will be used. + /// A set of customizations for how the client proxy is wired up. If , default options will be used. /// /// An instance of the generated proxy. /// In addition to implementing , it also implements @@ -733,7 +733,7 @@ public T Attach() /// Creates a JSON-RPC client proxy that conforms to the specified server interface. /// /// The interface that describes the functions available on the remote end. - /// A set of customizations for how the client proxy is wired up. If null, default options will be used. + /// A set of customizations for how the client proxy is wired up. If , default options will be used. /// An instance of the generated proxy. public T Attach(JsonRpcProxyOptions? options) where T : class @@ -754,7 +754,7 @@ public T Attach(JsonRpcProxyOptions? options) /// Creates a JSON-RPC client proxy that conforms to the specified server interface. /// /// The interface that describes the functions available on the remote end. - /// A set of customizations for how the client proxy is wired up. If null, default options will be used. + /// A set of customizations for how the client proxy is wired up. If , default options will be used. /// An instance of the generated proxy. public object Attach(Type interfaceType, JsonRpcProxyOptions? options) { @@ -776,7 +776,7 @@ public void AddLocalRpcTarget(T target, JsonRpcTargetOptions? options) where T : notnull => this.AddLocalRpcTarget(typeof(T), target, options); /// - /// Thrown if called after is called and is false. + /// Thrown if called after is called and is . public void AddLocalRpcTarget(Type exposingMembersOn, object target, JsonRpcTargetOptions? options) { Requires.NotNull(exposingMembersOn, nameof(exposingMembersOn)); @@ -814,7 +814,7 @@ public void AddRemoteRpcTarget(JsonRpc remoteTarget) /// The method or delegate to invoke when a matching RPC message arrives. /// This method may accept parameters from the incoming JSON-RPC message. /// - /// Thrown if called after is called and is false. + /// Thrown if called after is called and is . public void AddLocalRpcMethod(string? rpcMethodName, Delegate handler) { Requires.NotNull(handler, nameof(handler)); @@ -833,7 +833,7 @@ public void AddLocalRpcMethod(string? rpcMethodName, Delegate handler) /// This method may accept parameters from the incoming JSON-RPC message. /// /// An instance of the type that defines which should handle the invocation. - /// Thrown if called after is called and is false. + /// Thrown if called after is called and is . public void AddLocalRpcMethod(string? rpcMethodName, MethodInfo handler, object? target) => this.AddLocalRpcMethod(handler, target, new JsonRpcMethodAttribute(rpcMethodName)); /// @@ -959,7 +959,7 @@ public Task InvokeWithParameterObjectAsync(string targetName, object? argument, /// An object whose properties match the names of parameters on the target method. Must be serializable using the selected . /// /// A dictionary of objects that describe how each entry in the provided in is expected by the server to be typed. - /// If specified, this must have exactly the same set of keys as and contain no null values. + /// If specified, this must have exactly the same set of keys as and contain no values. /// /// /// @@ -1172,7 +1172,7 @@ internal static T MarshalLimitedArgument(T marshaledObject) } /// - /// Thrown if called after is called and is false. + /// Thrown if called after is called and is . internal void AddLocalRpcMethod(MethodInfo handler, object? target, JsonRpcMethodAttribute? methodRpcSettings, SynchronizationContext? synchronizationContext) { this.ThrowIfConfigurationLocked(); @@ -1238,7 +1238,7 @@ internal void AddLocalRpcMethod(MethodInfo handler, object? target, JsonRpcMetho /// /// Disposes managed and native resources held by this instance. /// - /// true if being disposed; false if being finalized. + /// if being disposed; if being finalized. protected virtual void Dispose(bool disposing) { if (!this.IsDisposed) @@ -1269,7 +1269,7 @@ protected virtual void Dispose(bool disposing) /// /// The request that led to the invocation that ended up failing. /// The exception thrown from the RPC method. - /// The error details to return to the client. Must not be null. + /// The error details to return to the client. Must not be . /// /// This method may be overridden in a derived class to change the way error details are expressed. /// @@ -1332,7 +1332,7 @@ protected virtual RemoteRpcException CreateExceptionFromRpcError(JsonRpcRequest /// /// The received error message. /// - /// The type, or null if the type is unknown. + /// The type, or if the type is unknown. /// /// /// The default implementation matches what does @@ -1405,15 +1405,15 @@ protected Task InvokeCoreAsync(RequestId id, string targetName /// RPC method return type. /// An identifier established by the Client. If the default value is given, it is assumed to be a notification. /// Name of the method to invoke. Must not be null or empty. - /// Arguments to pass to the invoked method. They must be serializable using the selected . If null, no arguments are passed. + /// Arguments to pass to the invoked method. They must be serializable using the selected . If , no arguments are passed. /// /// A list of objects that describe how each element in is expected by the server to be typed. - /// If specified, this must have exactly the same length as and contain no null elements. + /// If specified, this must have exactly the same length as and contain no elements. /// This value is ignored when is true. /// /// /// A dictionary of objects that describe how each entry in the provided in the only element of is expected by the server to be typed. - /// If specified, this must have exactly the same set of keys as the dictionary contained in the first element of , and contain no null values. + /// If specified, this must have exactly the same set of keys as the dictionary contained in the first element of , and contain no values. /// /// The token whose cancellation should signal the server to stop processing this request. /// Value which indicates if parameter should be passed as an object. @@ -1699,7 +1699,7 @@ private static Exception StripExceptionToInnerException(Exception exception) /// /// The original type of the value returned from an RPC-invoked method. /// Receives the type that is a base type of , if found. - /// true if could be found in the type hierarchy; otherwise false. + /// if could be found in the type hierarchy; otherwise . private static bool TryGetTaskOfTOrValueTaskOfTType(TypeInfo taskTypeInfo, [NotNullWhen(true)] out TypeInfo? taskOfTTypeInfo) { Requires.NotNull(taskTypeInfo, nameof(taskTypeInfo)); @@ -1727,8 +1727,8 @@ private static bool TryGetTaskOfTOrValueTaskOfTType(TypeInfo taskTypeInfo, [NotN /// Convert a or into a if possible. /// /// The result from the RPC method invocation. - /// Receives the converted object, if conversion was possible; otherwise null. - /// true if conversion succeeded; false otherwise. + /// Receives the converted object, if conversion was possible; otherwise . + /// if conversion succeeded; otherwise. private static bool TryGetTaskFromValueTask(object? result, [NotNullWhen(true)] out Task? task) { if (result is ValueTask resultingValueTask) @@ -2593,9 +2593,9 @@ private void CancelPendingOutboundRequest(object state) /// /// Throws an exception if we have already started listening, - /// unless is true. + /// unless is . /// - /// Thrown if is true and is false. + /// Thrown if is and is . private void ThrowIfConfigurationLocked() { // PERF: This can get called a lot in scenarios where connections are short-lived and frequent. diff --git a/src/StreamJsonRpc/JsonRpcTargetOptions.cs b/src/StreamJsonRpc/JsonRpcTargetOptions.cs index f638d704..be53102f 100644 --- a/src/StreamJsonRpc/JsonRpcTargetOptions.cs +++ b/src/StreamJsonRpc/JsonRpcTargetOptions.cs @@ -48,16 +48,16 @@ public JsonRpcTargetOptions(JsonRpcTargetOptions copyFrom) /// Gets or sets a value indicating whether events raised on the target object /// should be relayed to the client via a JSON-RPC notify message. /// - /// The default is true. + /// The default is . public bool NotifyClientOfEvents { get; set; } = true; /// /// Gets or sets a value indicating whether non-public methods/events on target objects can be invoked /// by remote clients. /// - /// The default value is false. + /// The default value is . /// - /// The default for this property was true in the 1.x versions. + /// The default for this property was in the 1.x versions. /// public bool AllowNonPublicInvocation { get; set; } diff --git a/src/StreamJsonRpc/MessageHandlerBase.cs b/src/StreamJsonRpc/MessageHandlerBase.cs index b16829a0..410fe556 100644 --- a/src/StreamJsonRpc/MessageHandlerBase.cs +++ b/src/StreamJsonRpc/MessageHandlerBase.cs @@ -115,8 +115,8 @@ private enum MessageHandlerState /// Reads a distinct and complete message from the transport, waiting for one if necessary. /// /// A token to cancel the read request. - /// The received message, or null if the underlying transport ends before beginning another message. - /// Thrown when returns false. + /// The received message, or if the underlying transport ends before beginning another message. + /// Thrown when returns . /// Thrown if the transport ends while reading a message. /// Thrown if is canceled before a new message is received. /// @@ -166,7 +166,7 @@ private enum MessageHandlerState /// The message to write. /// A token to cancel the write request. /// A task that represents the asynchronous operation. - /// Thrown when returns false. + /// Thrown when returns . /// Thrown if is canceled before message transmission begins. /// Thrown if this instance is disposed before or during transmission. /// @@ -270,7 +270,7 @@ public virtual async Task DisposeAsync() /// /// Disposes resources allocated by this instance that are common to both reading and writing. /// - /// true when being disposed; false when being finalized. + /// when being disposed; when being finalized. /// /// /// This method is called by after both and have completed. diff --git a/src/StreamJsonRpc/MessagePackFormatter.cs b/src/StreamJsonRpc/MessagePackFormatter.cs index ea617e30..7e9b5ab9 100644 --- a/src/StreamJsonRpc/MessagePackFormatter.cs +++ b/src/StreamJsonRpc/MessagePackFormatter.cs @@ -391,7 +391,7 @@ public void Dispose() /// /// Disposes managed and native resources held by this instance. /// - /// true if being disposed; false if being finalized. + /// if being disposed; if being finalized. protected virtual void Dispose(bool disposing) { this.duplexPipeTracker?.Dispose(); @@ -401,7 +401,7 @@ protected virtual void Dispose(bool disposing) /// Extracts a dictionary of property names and values from the specified params object. /// /// The params object. - /// A dictionary of argument values and another of declared argument types, or null if is null. + /// A dictionary of argument values and another of declared argument types, or if is null. /// /// This method supports DataContractSerializer-compliant types. This includes C# anonymous types. /// @@ -743,7 +743,7 @@ private RawMessagePack(ReadOnlyMemory raw) /// Reads one raw messagepack token. /// /// The reader to use. - /// true if the token must outlive the lifetime of the reader's underlying buffer; false otherwise. + /// if the token must outlive the lifetime of the reader's underlying buffer; otherwise. /// The raw messagepack slice. internal static RawMessagePack ReadRaw(ref MessagePackReader reader, bool copy) { diff --git a/src/StreamJsonRpc/PipeMessageHandler.cs b/src/StreamJsonRpc/PipeMessageHandler.cs index 72fad890..9d4d64c3 100644 --- a/src/StreamJsonRpc/PipeMessageHandler.cs +++ b/src/StreamJsonRpc/PipeMessageHandler.cs @@ -160,13 +160,13 @@ protected override async ValueTask FlushAsync(CancellationToken cancellationToke /// Reads from the until at least a specified number of bytes are available. /// /// The number of bytes that must be available. - /// true to allow returning 0 bytes if the end of the stream is encountered before any bytes are read. + /// to allow returning 0 bytes if the end of the stream is encountered before any bytes are read. /// A cancellation token. /// The containing at least bytes. /// Thrown if . /// /// Thrown if before we have bytes. - /// Not thrown if 0 bytes were read and is true. + /// Not thrown if 0 bytes were read and is . /// protected async ValueTask ReadAtLeastAsync(int requiredBytes, bool allowEmpty, CancellationToken cancellationToken) { @@ -206,7 +206,7 @@ protected async ValueTask ReadAtLeastAsync(int requiredBytes, bool a /// /// The length of the JSON-RPC message. /// The encoding to use during deserialization, as specified in a header for this particular message. - /// The encoding to use when is null if the supports encoding. + /// The encoding to use when is if the supports encoding. /// A cancellation token. /// The deserialized message. /// Thrown if is non-null and the formatter does not implement the appropriate interface to supply the encoding. diff --git a/src/StreamJsonRpc/Protocol/IJsonRpcMessageWithId.cs b/src/StreamJsonRpc/Protocol/IJsonRpcMessageWithId.cs index 9222c2f4..99e5a9bb 100644 --- a/src/StreamJsonRpc/Protocol/IJsonRpcMessageWithId.cs +++ b/src/StreamJsonRpc/Protocol/IJsonRpcMessageWithId.cs @@ -4,7 +4,7 @@ namespace StreamJsonRpc.Protocol; /// -/// An interface found on JSON-RPC protocol messages that contain an
id
field. +/// An interface found on JSON-RPC protocol messages that contain an id field. ///
public interface IJsonRpcMessageWithId { diff --git a/src/StreamJsonRpc/Protocol/JsonRpcError.cs b/src/StreamJsonRpc/Protocol/JsonRpcError.cs index f8a70a67..44537f30 100644 --- a/src/StreamJsonRpc/Protocol/JsonRpcError.cs +++ b/src/StreamJsonRpc/Protocol/JsonRpcError.cs @@ -24,7 +24,7 @@ public class JsonRpcError : JsonRpcMessage, IJsonRpcMessageWithId /// /// Gets or sets an identifier established by the client if a response to the request is expected. /// - /// A , an , a , or null. + /// A , an , a , or . [Obsolete("Use " + nameof(RequestId) + " instead.")] [IgnoreDataMember] public object? Id diff --git a/src/StreamJsonRpc/Protocol/JsonRpcRequest.cs b/src/StreamJsonRpc/Protocol/JsonRpcRequest.cs index 5c08a982..dce9912f 100644 --- a/src/StreamJsonRpc/Protocol/JsonRpcRequest.cs +++ b/src/StreamJsonRpc/Protocol/JsonRpcRequest.cs @@ -63,7 +63,7 @@ public enum ArgumentMatchResult /// /// Gets or sets an identifier established by the client if a response to the request is expected. /// - /// A , an , a , or null. + /// A , an , a , or . [Obsolete("Use " + nameof(RequestId) + " instead.")] [IgnoreDataMember] public object? Id @@ -108,7 +108,7 @@ public object? Id /// /// Gets or sets a dictionary of objects indexed by the property name that describe how each element in is expected by the server to be typed. - /// If specified, this must have exactly the same size as and contain no null values. + /// If specified, this must have exactly the same size as and contain no values. /// /// /// This property is *not* serialized into the JSON-RPC message. @@ -144,7 +144,7 @@ public IReadOnlyList? ArgumentsList /// /// Gets or sets a list of objects that describe how each element in is expected by the server to be typed. - /// If specified, this must have exactly the same length as and contain no null elements. + /// If specified, this must have exactly the same length as and contain no elements. /// /// /// This property is *not* serialized into the JSON-RPC message. @@ -188,7 +188,7 @@ public IReadOnlyList? ArgumentsList /// An array to initialize with arguments that can satisfy CLR type requirements for each of the . /// The length of this span must equal the length of . /// - /// true if all the arguments can conform to the types of the and is initialized; false otherwise. + /// if all the arguments can conform to the types of the and is initialized; otherwise. /// Thrown if the argument exists, but cannot be deserialized. public virtual ArgumentMatchResult TryGetTypedArguments(ReadOnlySpan parameters, Span typedArguments) { @@ -246,7 +246,7 @@ public virtual ArgumentMatchResult TryGetTypedArguments(ReadOnlySpanThe index of the parameter that requires an argument. May be -1 for an argument with no position. /// The type of the parameter that requires an argument. May be null if the type need not be coerced. /// Receives the value of the argument, if it exists. It MAY be returned even if it does not conform to . - /// true if an argument is available for a parameter with the given name or position; false otherwise. + /// if an argument is available for a parameter with the given name or position; otherwise. /// /// A derived-type may override this method in order to consider the /// and deserialize the required argument on-demand such that it can satisfy the type requirement. diff --git a/src/StreamJsonRpc/Protocol/JsonRpcResult.cs b/src/StreamJsonRpc/Protocol/JsonRpcResult.cs index d650c780..e05b98ba 100644 --- a/src/StreamJsonRpc/Protocol/JsonRpcResult.cs +++ b/src/StreamJsonRpc/Protocol/JsonRpcResult.cs @@ -34,7 +34,7 @@ public class JsonRpcResult : JsonRpcMessage, IJsonRpcMessageWithId /// /// Gets or sets an identifier established by the client if a response to the request is expected. /// - /// A , an , a , or null. + /// A , an , a , or . [Obsolete("Use " + nameof(RequestId) + " instead.")] [IgnoreDataMember] public object? Id diff --git a/src/StreamJsonRpc/ProxyGeneration.cs b/src/StreamJsonRpc/ProxyGeneration.cs index aa407223..16f12956 100644 --- a/src/StreamJsonRpc/ProxyGeneration.cs +++ b/src/StreamJsonRpc/ProxyGeneration.cs @@ -603,8 +603,8 @@ private static void ImplementIsDisposedProperty(TypeBuilder proxyTypeBuilder, Fi /// Converts the value on the stack to one compatible with the method's return type. /// /// The interface method that we're generating code for. - /// true if the return type is or ; false otherwise. - /// true if the return type is ; false otherwise. + /// if the return type is or ; otherwise. + /// if the return type is ; otherwise. /// The IL emitter for the method. /// The Invoke method on that IL was just emitted to invoke. /// The parameter in the proxy method, if there is one. diff --git a/src/StreamJsonRpc/Reflection/IJsonRpcFormatterState.cs b/src/StreamJsonRpc/Reflection/IJsonRpcFormatterState.cs index 4764f6b3..b69e3749 100644 --- a/src/StreamJsonRpc/Reflection/IJsonRpcFormatterState.cs +++ b/src/StreamJsonRpc/Reflection/IJsonRpcFormatterState.cs @@ -23,7 +23,7 @@ public interface IJsonRpcFormatterState /// Gets a value indicating whether a is being serialized. /// /// - /// A response is being serialized if this property's value is false while is non-empty. + /// A response is being serialized if this property's value is while is non-empty. /// public bool SerializingRequest { get; } } diff --git a/src/StreamJsonRpc/Reflection/JsonRpcMethodAttribute.cs b/src/StreamJsonRpc/Reflection/JsonRpcMethodAttribute.cs index 50beccf8..cad2cf93 100644 --- a/src/StreamJsonRpc/Reflection/JsonRpcMethodAttribute.cs +++ b/src/StreamJsonRpc/Reflection/JsonRpcMethodAttribute.cs @@ -47,7 +47,7 @@ public JsonRpcMethodAttribute() /// /// Gets the public RPC name by which this method will be invoked. /// - /// May be null if the method's name has not been overridden. + /// May be if the method's name has not been overridden. public string? Name { get; } /// diff --git a/src/StreamJsonRpc/Reflection/MessageFormatterDuplexPipeTracker.cs b/src/StreamJsonRpc/Reflection/MessageFormatterDuplexPipeTracker.cs index 25f8ada9..b9c0f61a 100644 --- a/src/StreamJsonRpc/Reflection/MessageFormatterDuplexPipeTracker.cs +++ b/src/StreamJsonRpc/Reflection/MessageFormatterDuplexPipeTracker.cs @@ -76,7 +76,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Gets or sets the multiplexing stream used to create and accept channels. /// /// - /// If this is null, some public methods will throw . + /// If this is , some public methods will throw . /// public MultiplexingStream? MultiplexingStream { get; set; } @@ -102,7 +102,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates a token to represent an as it is transmitted from the client to an RPC server as a method argument. /// /// The client pipe that is to be shared with the RPC server. May be null. - /// The token to use as the RPC method argument; or null if was null. + /// The token to use as the RPC method argument; or if was . /// Thrown if no was provided to the constructor or when serializing a message without an ID property. [return: NotNullIfNotNull("duplexPipe")] public ulong? GetULongToken(IDuplexPipe? duplexPipe) @@ -150,7 +150,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates a token to represent a as it is transmitted from the client to an RPC server as a method argument. /// /// The client pipe that is to be shared with the RPC server. May be null. - /// The token to use as the RPC method argument; or null if was null. + /// The token to use as the RPC method argument; or if was . /// Thrown if no was provided to the constructor or when serializing a message without an ID property. [return: NotNullIfNotNull("reader")] public ulong? GetULongToken(PipeReader? reader) => this.GetULongToken(reader is not null ? new DuplexPipe(reader) : null); @@ -164,7 +164,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates a token to represent a as it is transmitted from the client to an RPC server as a method argument. /// /// The client pipe that is to be shared with the RPC server. May be null. - /// The token to use as the RPC method argument; or null if was null. + /// The token to use as the RPC method argument; or if was . /// Thrown if no was provided to the constructor or when serializing a message without an ID property. [return: NotNullIfNotNull("writer")] public ulong? GetULongToken(PipeWriter? writer) => this.GetULongToken(writer is not null ? new DuplexPipe(writer) : null); @@ -178,7 +178,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates an from a given token as it is received at the RPC server as a method argument. /// /// The method argument, which was originally obtained by the client using the method. - /// The from the token; or null if was null. + /// The from the token; or if was . /// Thrown if the token does not match up with an out of band channel offered by the client. /// Thrown if no was provided to the constructor. [return: NotNullIfNotNull("token")] @@ -223,7 +223,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates a from a given token as it is received at the RPC server as a method argument. /// /// The method argument, which was originally obtained by the client using the method. - /// The from the token; or null if was null. + /// The from the token; or if was . /// Thrown if the token does not match up with an out of band channel offered by the client. /// Thrown if no was provided to the constructor. [return: NotNullIfNotNull("token")] @@ -248,7 +248,7 @@ public MessageFormatterDuplexPipeTracker(JsonRpc jsonRpc, IJsonRpcFormatterState /// Creates a from a given token as it is received at the RPC server as a method argument. /// /// The method argument, which was originally obtained by the client using the method. - /// The from the token; or null if was null. + /// The from the token; or if was . /// Thrown if the token does not match up with an out of band channel offered by the client. /// Thrown if no was provided to the constructor. [return: NotNullIfNotNull("token")] @@ -274,7 +274,7 @@ public void Dispose() /// /// Disposes managed and native resources held by this instance. /// - /// true if being disposed; false if being finalized. + /// if being disposed; if being finalized. protected virtual void Dispose(bool disposing) { this.isDisposed = true; @@ -339,7 +339,7 @@ private void CleanUpOutboundResources(RequestId requestId, bool successful) } /// - /// Throws if is null. + /// Throws if is . /// private MultiplexingStream GetMultiplexingStreamOrThrow() { diff --git a/src/StreamJsonRpc/Reflection/MessageFormatterEnumerableTracker.cs b/src/StreamJsonRpc/Reflection/MessageFormatterEnumerableTracker.cs index 3a13ea7e..defcf416 100644 --- a/src/StreamJsonRpc/Reflection/MessageFormatterEnumerableTracker.cs +++ b/src/StreamJsonRpc/Reflection/MessageFormatterEnumerableTracker.cs @@ -133,7 +133,7 @@ public long GetToken(IAsyncEnumerable enumerable) /// and gets all its values from a remote generator. /// /// The type of value that is produced by the enumerable. - /// The handle specified by the generator that is used to obtain more values or dispose of the enumerator. May be null to indicate there will be no more values. + /// The handle specified by the generator that is used to obtain more values or dispose of the enumerator. May be to indicate there will be no more values. /// The list of items that are included with the enumerable handle. /// The enumerator. #pragma warning disable VSTHRD200 // Use "Async" suffix in names of methods that return an awaitable type. diff --git a/src/StreamJsonRpc/Reflection/MessageFormatterProgressTracker.cs b/src/StreamJsonRpc/Reflection/MessageFormatterProgressTracker.cs index cee9c91a..f3af5b93 100644 --- a/src/StreamJsonRpc/Reflection/MessageFormatterProgressTracker.cs +++ b/src/StreamJsonRpc/Reflection/MessageFormatterProgressTracker.cs @@ -69,7 +69,7 @@ public MessageFormatterProgressTracker(JsonRpc jsonRpc, IJsonRpcFormatterState f /// Converts given to its type. /// /// The type which may implement . - /// The from given object, or null if no such interface was found in the given . + /// The from given object, or if no such interface was found in the given . public static Type? FindIProgressOfT(Type objectType) => TrackerHelpers>.FindInterfaceImplementedBy(objectType); /// diff --git a/src/StreamJsonRpc/Reflection/MessageFormatterRpcMarshaledContextTracker.cs b/src/StreamJsonRpc/Reflection/MessageFormatterRpcMarshaledContextTracker.cs index 2fda9df0..b8d46c20 100644 --- a/src/StreamJsonRpc/Reflection/MessageFormatterRpcMarshaledContextTracker.cs +++ b/src/StreamJsonRpc/Reflection/MessageFormatterRpcMarshaledContextTracker.cs @@ -191,7 +191,7 @@ internal MarshalToken GetToken(IRpcMarshaledContext marshaledContext) /// The interface the proxy must implement. /// The token received from the remote party that includes the handle to the remote object. /// The options to feed into proxy generation. - /// The generated proxy, or null if is null. + /// The generated proxy, or if is null. [return: NotNullIfNotNull("token")] internal object? GetObject(Type interfaceType, MarshalToken? token, JsonRpcProxyOptions options) { @@ -239,7 +239,7 @@ internal MarshalToken GetToken(IRpcMarshaledContext marshaledContext) /// Releases memory associated with marshaled objects. /// /// The handle to the object as created by the method. - /// true if the was created by (and thus the original object owned by) the remote party; false if the token and object was created locally. + /// if the was created by (and thus the original object owned by) the remote party; if the token and object was created locally. #pragma warning disable CA1801 // Review unused parameters -- Signature is dicated by protocol extension server method. private void ReleaseMarshaledObject(long handle, bool ownedBySender) #pragma warning restore CA1801 // Review unused parameters diff --git a/src/StreamJsonRpc/Reflection/RpcTargetInfo.cs b/src/StreamJsonRpc/Reflection/RpcTargetInfo.cs index d98ac1e8..38e9bbc0 100644 --- a/src/StreamJsonRpc/Reflection/RpcTargetInfo.cs +++ b/src/StreamJsonRpc/Reflection/RpcTargetInfo.cs @@ -24,7 +24,7 @@ internal class RpcTargetInfo : System.IAsyncDisposable private readonly Dictionary> targetRequestMethodToClrMethodMap = new Dictionary>(StringComparer.Ordinal); /// - /// A list of event handlers we've registered on target objects that define events. May be null if there are no handlers. + /// A list of event handlers we've registered on target objects that define events. May be if there are no handlers. /// private List? eventReceivers; @@ -173,9 +173,9 @@ internal bool TryGetTargetMethod(JsonRpcRequest request, [NotNullWhen(true)] out /// If this type is not an interface, only public members become invokable unless is set to true on the argument. /// /// Target to invoke when incoming messages are received. - /// A set of customizations for how the target object is registered. If null, default options will be used. + /// A set of customizations for how the target object is registered. If , default options will be used. /// to receive an that can remove the target object; otherwise. - /// An object that may be disposed of to revert the addition of the target object. Will be null if and only if is false. + /// An object that may be disposed of to revert the addition of the target object. Will be null if and only if is . /// /// When multiple target objects are added, the first target with a method that matches a request is invoked. /// @@ -277,7 +277,7 @@ internal bool TryGetTargetMethod(JsonRpcRequest request, [NotNullWhen(true)] out /// /// A description for how this method should be treated. /// It need not be an attribute that was actually applied to . - /// An attribute will *not* be discovered via reflection on the , even if this value is null. + /// An attribute will *not* be discovered via reflection on the , even if this value is . /// /// The to schedule the method invocation on instead of the default one specified by the property. internal void AddLocalRpcMethod(MethodInfo handler, object? target, JsonRpcMethodAttribute? methodRpcSettings, SynchronizationContext? synchronizationContext) diff --git a/src/StreamJsonRpc/Reflection/TrackerHelpers.cs b/src/StreamJsonRpc/Reflection/TrackerHelpers.cs index bd6ecc39..929b32fb 100644 --- a/src/StreamJsonRpc/Reflection/TrackerHelpers.cs +++ b/src/StreamJsonRpc/Reflection/TrackerHelpers.cs @@ -26,7 +26,7 @@ internal static class TrackerHelpers /// Extracts some interface from a given , if it is implemented. /// /// The type which may implement . - /// The type from given object, or null if no such interface was found in the given . + /// The type from given object, or if no such interface was found in the given . internal static Type? FindInterfaceImplementedBy(Type objectType) { Requires.NotNull(objectType, nameof(objectType)); @@ -60,13 +60,13 @@ internal static class TrackerHelpers /// Checks whether the given type is an interface compatible with . /// /// The type that may be deserialized. - /// true if is a closed generic form of ; false otherwise. + /// if is a closed generic form of ; otherwise. internal static bool CanDeserialize(Type objectType) => IsActualInterfaceMatch(objectType); /// /// Checks whether the given type is an interface compatible with . /// /// The type that may be deserialized. - /// true if is a closed generic form of ; false otherwise. + /// if is a closed generic form of ; otherwise. internal static bool IsActualInterfaceMatch(Type objectType) => Requires.NotNull(objectType, nameof(objectType)).IsConstructedGenericType && objectType.GetGenericTypeDefinition().Equals(InterfaceGenericTypeDefinition); } diff --git a/src/StreamJsonRpc/RequestId.cs b/src/StreamJsonRpc/RequestId.cs index 5189f701..9a2a2498 100644 --- a/src/StreamJsonRpc/RequestId.cs +++ b/src/StreamJsonRpc/RequestId.cs @@ -41,7 +41,7 @@ public RequestId(string? id) public static RequestId NotSpecified => default; /// - /// Gets the special value for an explicitly specified null request ID. + /// Gets the special value for an explicitly specified request ID. /// public static RequestId Null => new RequestId(null); @@ -86,7 +86,7 @@ public RequestId(string? id) /// /// The first value. /// The second value. - /// true if the values are equal; false otherwise. + /// if the values are equal; otherwise. public static bool operator ==(RequestId first, RequestId second) => first.Equals(second); /// @@ -94,7 +94,7 @@ public RequestId(string? id) /// /// The first value. /// The second value. - /// false if the values are equal; true otherwise. + /// if the values are equal; otherwise. public static bool operator !=(RequestId first, RequestId second) => !(first == second); /// diff --git a/src/StreamJsonRpc/StreamMessageHandler.cs b/src/StreamJsonRpc/StreamMessageHandler.cs index cf5b5c6c..650df82f 100644 --- a/src/StreamJsonRpc/StreamMessageHandler.cs +++ b/src/StreamJsonRpc/StreamMessageHandler.cs @@ -50,7 +50,7 @@ protected StreamMessageHandler(Stream? sendingStream, Stream? receivingStream, I /// /// Disposes resources allocated by this instance. /// - /// true when being disposed; false when being finalized. + /// when being disposed; when being finalized. protected override void Dispose(bool disposing) { if (disposing) diff --git a/test/StreamJsonRpc.Tests/FullDuplexStream.cs b/test/StreamJsonRpc.Tests/FullDuplexStream.cs index 94aa6964..4e64dddc 100644 --- a/test/StreamJsonRpc.Tests/FullDuplexStream.cs +++ b/test/StreamJsonRpc.Tests/FullDuplexStream.cs @@ -274,7 +274,7 @@ internal Message(byte[] buffer) /// and should be removed from the queue. /// /// - /// This returns false if the buffer was originally empty, + /// This returns if the buffer was originally empty, /// since that signifies that the other party closed their sending stream. /// public bool IsConsumed => this.Position == this.Buffer.Length && this.Buffer.Length > 0; diff --git a/test/StreamJsonRpc.Tests/TestBase.cs b/test/StreamJsonRpc.Tests/TestBase.cs index ee1d59d7..f1cd0674 100644 --- a/test/StreamJsonRpc.Tests/TestBase.cs +++ b/test/StreamJsonRpc.Tests/TestBase.cs @@ -51,8 +51,8 @@ public void Dispose() /// /// The type of exception sought. /// The exception to search. - /// true to require an exact match; false to allow match on derived types of . - /// true if an exception of type was found at or under . + /// to require an exact match; to allow match on derived types of . + /// if an exception of type was found at or under . protected static bool IsExceptionOrInnerOfType(Exception? ex, bool exactTypeMatch = false) => FindExceptionOrInner(ex, x => exactTypeMatch ? (x.GetType() == typeof(TException)) : x is TException) is object; /// @@ -60,7 +60,7 @@ public void Dispose() /// /// The starting exception to search. /// The test for whether this exception is the one sought for. - /// The first in the exception tree for which returns true, or null if the never returned true. + /// The first in the exception tree for which returns , or if the never returned . protected static Exception? FindExceptionOrInner(Exception? ex, Func predicate) { if (ex is null)