├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── SUPPORT.md ├── docs └── assets │ ├── intro.gif │ ├── nuget-screenshot1.png │ ├── nuget-screenshot2.png │ └── vs-screenshot1.png ├── src ├── InclusivenessAnalyzer.sln ├── InclusivenessAnalyzer │ ├── InclusivenessAnalyzer.CodeFixes │ │ ├── CodeFixResources.Designer.cs │ │ ├── CodeFixResources.resx │ │ ├── InclusivenessAnalyzer.CodeFixes.csproj │ │ └── InclusivenessAnalyzerCodeFixProvider.cs │ ├── InclusivenessAnalyzer.Package │ │ ├── InclusivenessAnalyzer.Package.csproj │ │ ├── icon.png │ │ └── tools │ │ │ ├── install.ps1 │ │ │ └── uninstall.ps1 │ ├── InclusivenessAnalyzer.Test │ │ ├── InclusivenessAnalyzer.Test.csproj │ │ ├── InclusivenessAnalyzerUnitTests.cs │ │ └── Verifiers │ │ │ ├── CSharpAnalyzerVerifier`1+Test.cs │ │ │ ├── CSharpAnalyzerVerifier`1.cs │ │ │ ├── CSharpCodeFixVerifier`2+Test.cs │ │ │ ├── CSharpCodeFixVerifier`2.cs │ │ │ ├── CSharpCodeRefactoringVerifier`1+Test.cs │ │ │ ├── CSharpCodeRefactoringVerifier`1.cs │ │ │ ├── CSharpVerifierHelper.cs │ │ │ ├── VisualBasicAnalyzerVerifier`1+Test.cs │ │ │ ├── VisualBasicAnalyzerVerifier`1.cs │ │ │ ├── VisualBasicCodeFixVerifier`2+Test.cs │ │ │ ├── VisualBasicCodeFixVerifier`2.cs │ │ │ ├── VisualBasicCodeRefactoringVerifier`1+Test.cs │ │ │ └── VisualBasicCodeRefactoringVerifier`1.cs │ ├── InclusivenessAnalyzer.Vsix │ │ ├── InclusivenessAnalyzer.Vsix.csproj │ │ └── source.extension.vsixmanifest │ ├── InclusivenessAnalyzer.Vsix2022 │ │ ├── InclusivenessAnalyzer.Vsix2022.csproj │ │ └── source.extension.vsixmanifest │ └── InclusivenessAnalyzer │ │ ├── InclusivenessAnalyzer.cs │ │ ├── InclusivenessAnalyzer.csproj │ │ ├── Resources.Designer.cs │ │ └── Resources.resx └── NuGet.config └── terms.md /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Inclusiveness Analyzer 2 | 3 | > Make your code inclusive! 4 | 5 | The Inclusiveness Analyzer is a Visual Studio extension that checks code for offensive / exclusive terms. 6 | 7 | It also provides context on why a word is exclusive and suggests alternate terms that can be used instead. 8 | 9 | ![Intro clip](docs/assets/intro.gif) 10 | 11 | ## Installing via the NuGet Package 12 | 13 | The Inclusiveness Analyzer can be added to any C# project. Just install using NuGet and start writing code. The extension will be automatically loaded in Visual Studio for anyone that opens your project. Using the NuGet package is best when you are working on a project with a team. 14 | 15 | [Get from NuGet](https://www.nuget.org/packages/InclusivenessAnalyzer/) 16 | 17 | ### Install using the NuGet Package Manager user interface 18 | 19 | * Open the C# project using Visual Studio 20 | * Select **Tools** from the menu 21 | * Select **NuGet Package Manager** 22 | * Select **Manage NuGet Packages for Solution...** 23 | * Select **Browse** 24 | * Search for **inclusiveness** 25 | * Select the checkbox next to the project(s) 26 | * Select **Install** 27 | 28 | ![Screenshot showing nuget install from user interface.](docs/assets/nuget-screenshot1.png) 29 | 30 | ### Install using the NuGet Package Manager console 31 | 32 | * Open the C# project using Visual Studio 33 | * Select **Tools** from the menu 34 | * Select **NuGet Package Manager** 35 | * Select **Package Manager Console** 36 | * Run `Install-Package InclusivenessAnalyzer` 37 | 38 | ![Screenshot showing nuget install from command line.](docs/assets/nuget-screenshot2.png) 39 | > Important Note: The Inclusiveness Analyzer is only used during development time and does not affect your projects outputs or binaries. 40 | 41 | ## Installing as a Visual Studio Extension 42 | 43 | If you would like the Inclusiveness Analyzer to run on any Visual Studio project you can install the extension directly into Visual Studio. 44 | 45 | * View and install [Inclusiveness Analyzer for Visual Studio 2022](https://marketplace.visualstudio.com/items?itemName=InclusivenessAnalyzer.inclusivenessanalyzer2022) 46 | * View and install [Inclusiveness Analyzer for Visual Studio 2019](https://marketplace.visualstudio.com/items?itemName=InclusivenessAnalyzer.inclusivenessanalyzer) 47 | 48 | * Open Visual Studio 2019 or Visual Studio 2022 49 | * Select **Extensions** from the menu 50 | * Select **Manage Extensions** 51 | * Search for **Inclusiveness** 52 | * Select **Download** 53 | 54 | The extension is scheduled for install. Your extension will be installed after all instances of Visual Studio have been closed. 55 | 56 | ![Screenshot showing Inclusiveness Analyzer being added to Visual Studio.](docs/assets/vs-screenshot1.png) 57 | 58 | Happy inclusive :heart: coding! 59 | 60 | ## Inclusiveness Analyzer for other Platforms 61 | 62 | * [Inclusiveness Analyzer GitHub Action](https://github.com/microsoft/InclusivenessAnalyzer) 63 | * [Inclusiveness Analyzer Azure DevOps Extension](https://github.com/microsoft/InclusivenessAnalyzerAzureDevOps) 64 | 65 | ## About the project 66 | 67 | As humans, we hold many unconscious and implicit biases that we rely on to react quickly to our environment and any novel stimuli. However, since the unconscious brain processes and reacts with speed, we sometimes speak quickly without thinking, which may cause us to slip offensive terms and stereotypes although we mean no malice. 68 | 69 | In order to confront these biases that we see in ourselves and others, we must rewire ourselves to regularly use inclusive practices (such as the words we speak). If you don't intentionally and proactively include, you will unintentionally exclude. 70 | 71 | > Join our effort to push out exclusive terms and make inclusive terms a part of our everyday vocabulary! 72 | 73 | Help us confront these biases by pushing out exclusive terms and making inclusive terms a part of our everyday vocabulary! 74 | 75 | > Icons made by [Freepik](https://www.flaticon.com/authors/freepik) from [www.flaticon.com](https://www.flaticon.com/) 76 | 77 | ## Contributing 78 | 79 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 80 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 81 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 82 | 83 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 84 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 85 | provided by the bot. You will only need to do this once across all repos using our CLA. 86 | 87 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 88 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 89 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 90 | 91 | ## Trademarks 92 | 93 | This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft 94 | trademarks or logos is subject to and must follow 95 | [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). 96 | Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. 97 | Any use of third-party trademarks or logos are subject to those third-party's policies. 98 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | 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/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | 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://aka.ms/opensource/security/pgpkey). 16 | 17 | 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://aka.ms/opensource/security/msrc). 18 | 19 | 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: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | 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://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /SUPPORT.md: -------------------------------------------------------------------------------- 1 | # TODO: The maintainer of this repo has not yet edited this file 2 | 3 | **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project? 4 | 5 | - **No CSS support:** Fill out this template with information about how to file issues and get help. 6 | - **Yes CSS support:** Fill out an intake form at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). CSS will work with/help you to determine next steps. 7 | - **Not sure?** Fill out an intake as though the answer were "Yes". CSS will help you decide. 8 | 9 | *Then remove this first heading from this SUPPORT.MD file before publishing your repo.* 10 | 11 | # Support 12 | 13 | ## How to file issues and get help 14 | 15 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing 16 | issues before filing new issues to avoid duplicates. For new issues, file your bug or 17 | feature request as a new Issue. 18 | 19 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE 20 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER 21 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**. 22 | 23 | ## Microsoft Support Policy 24 | 25 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above. 26 | -------------------------------------------------------------------------------- /docs/assets/intro.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/InclusivenessAnalyzerVisualStudio/c9449dc604f453211877e61beaae5e187a74f5b2/docs/assets/intro.gif -------------------------------------------------------------------------------- /docs/assets/nuget-screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/InclusivenessAnalyzerVisualStudio/c9449dc604f453211877e61beaae5e187a74f5b2/docs/assets/nuget-screenshot1.png -------------------------------------------------------------------------------- /docs/assets/nuget-screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/InclusivenessAnalyzerVisualStudio/c9449dc604f453211877e61beaae5e187a74f5b2/docs/assets/nuget-screenshot2.png -------------------------------------------------------------------------------- /docs/assets/vs-screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/InclusivenessAnalyzerVisualStudio/c9449dc604f453211877e61beaae5e187a74f5b2/docs/assets/vs-screenshot1.png -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32819.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer", "InclusivenessAnalyzer\InclusivenessAnalyzer\InclusivenessAnalyzer.csproj", "{50988C99-C9FC-4162-91AB-3A660B236130}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer.CodeFixes", "InclusivenessAnalyzer\InclusivenessAnalyzer.CodeFixes\InclusivenessAnalyzer.CodeFixes.csproj", "{2B3399FE-CD84-4007-B22B-0E1458F16D0A}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer.Package", "InclusivenessAnalyzer\InclusivenessAnalyzer.Package\InclusivenessAnalyzer.Package.csproj", "{4F6045EC-2BEC-4DC7-83FC-BAA0FB531D8A}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer.Test", "InclusivenessAnalyzer\InclusivenessAnalyzer.Test\InclusivenessAnalyzer.Test.csproj", "{15AEA91F-A180-4244-A73F-3F6E05CAA435}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer.Vsix", "InclusivenessAnalyzer\InclusivenessAnalyzer.Vsix\InclusivenessAnalyzer.Vsix.csproj", "{F2280C55-4A32-40AA-9345-593C438E2B85}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InclusivenessAnalyzer.Vsix2022", "InclusivenessAnalyzer\InclusivenessAnalyzer.Vsix2022\InclusivenessAnalyzer.Vsix2022.csproj", "{C40A78E2-EBEE-462C-8B13-DEEDD94039F4}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {50988C99-C9FC-4162-91AB-3A660B236130}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {50988C99-C9FC-4162-91AB-3A660B236130}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {50988C99-C9FC-4162-91AB-3A660B236130}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {50988C99-C9FC-4162-91AB-3A660B236130}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {2B3399FE-CD84-4007-B22B-0E1458F16D0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {2B3399FE-CD84-4007-B22B-0E1458F16D0A}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {2B3399FE-CD84-4007-B22B-0E1458F16D0A}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {2B3399FE-CD84-4007-B22B-0E1458F16D0A}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {4F6045EC-2BEC-4DC7-83FC-BAA0FB531D8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {4F6045EC-2BEC-4DC7-83FC-BAA0FB531D8A}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {4F6045EC-2BEC-4DC7-83FC-BAA0FB531D8A}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {4F6045EC-2BEC-4DC7-83FC-BAA0FB531D8A}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {15AEA91F-A180-4244-A73F-3F6E05CAA435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {15AEA91F-A180-4244-A73F-3F6E05CAA435}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {15AEA91F-A180-4244-A73F-3F6E05CAA435}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {15AEA91F-A180-4244-A73F-3F6E05CAA435}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {F2280C55-4A32-40AA-9345-593C438E2B85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {F2280C55-4A32-40AA-9345-593C438E2B85}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {F2280C55-4A32-40AA-9345-593C438E2B85}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {F2280C55-4A32-40AA-9345-593C438E2B85}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {C40A78E2-EBEE-462C-8B13-DEEDD94039F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {C40A78E2-EBEE-462C-8B13-DEEDD94039F4}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {C40A78E2-EBEE-462C-8B13-DEEDD94039F4}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {C40A78E2-EBEE-462C-8B13-DEEDD94039F4}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {34F5BA6B-6259-4847-85A5-0C785A9BD1DA} 54 | EndGlobalSection 55 | EndGlobal 56 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.CodeFixes/CodeFixResources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace InclusivenessAnalyzer { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class CodeFixResources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal CodeFixResources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("InclusivenessAnalyzer.CodeFixResources", typeof(CodeFixResources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Make inclusive. 65 | /// 66 | internal static string CodeFixTitle { 67 | get { 68 | return ResourceManager.GetString("CodeFixTitle", resourceCulture); 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.CodeFixes/CodeFixResources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Make inclusive 122 | The title of the code fix. 123 | 124 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.CodeFixes/InclusivenessAnalyzer.CodeFixes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | false 6 | InclusivenessAnalyzer 7 | 1.3.0 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.CodeFixes/InclusivenessAnalyzerCodeFixProvider.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeActions; 3 | using Microsoft.CodeAnalysis.CodeFixes; 4 | using Microsoft.CodeAnalysis.CSharp; 5 | using Microsoft.CodeAnalysis.CSharp.Syntax; 6 | using Microsoft.CodeAnalysis.Rename; 7 | using Microsoft.CodeAnalysis.Text; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Collections.Immutable; 11 | using System.Composition; 12 | using System.Linq; 13 | using System.Threading; 14 | using System.Threading.Tasks; 15 | 16 | namespace InclusivenessAnalyzer 17 | { 18 | [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(InclusivenessAnalyzerCodeFixProvider)), Shared] 19 | public class InclusivenessAnalyzerCodeFixProvider : CodeFixProvider 20 | { 21 | public sealed override ImmutableArray FixableDiagnosticIds 22 | { 23 | get { return ImmutableArray.Create(InclusivenessAnalyzer.DiagnosticId); } 24 | } 25 | 26 | public sealed override FixAllProvider GetFixAllProvider() 27 | { 28 | // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers 29 | return WellKnownFixAllProviders.BatchFixer; 30 | } 31 | 32 | public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) 33 | { 34 | //var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); 35 | 36 | //// TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest 37 | //var diagnostic = context.Diagnostics.First(); 38 | //var diagnosticSpan = diagnostic.Location.SourceSpan; 39 | 40 | //// Find the type declaration identified by the diagnostic. 41 | //var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); 42 | 43 | //// Register a code action that will invoke the fix. 44 | //context.RegisterCodeFix( 45 | // CodeAction.Create( 46 | // title: CodeFixResources.CodeFixTitle, 47 | // createChangedSolution: c => MakeInclusiveAsync(context.Document, declaration, c), 48 | // equivalenceKey: nameof(CodeFixResources.CodeFixTitle)), 49 | // diagnostic); 50 | } 51 | 52 | private async Task MakeInclusiveAsync(Document document, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken) 53 | { 54 | // Compute new inclusive name. 55 | var identifierToken = typeDecl.Identifier; 56 | var newName = identifierToken.Text.Replace("WhiteList", "AllowList"); 57 | 58 | // Get the symbol representing the type to be renamed. 59 | var semanticModel = await document.GetSemanticModelAsync(cancellationToken); 60 | var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken); 61 | 62 | // Produce a new solution that has all references to that type renamed, including the declaration. 63 | var originalSolution = document.Project.Solution; 64 | var optionSet = originalSolution.Workspace.Options; 65 | var newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, typeSymbol, newName, optionSet, cancellationToken).ConfigureAwait(false); 66 | 67 | // Return the new solution with the now-inclusive type name. 68 | return newSolution; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Package/InclusivenessAnalyzer.Package.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | false 6 | true 7 | true 8 | 9 | 10 | 11 | InclusivenessAnalyzer 12 | 1.3.0.0 13 | Sana, Jo, Bliss, Merill 14 | 15 | https://github.com/microsoft/InclusivenessAnalyzerVisualStudio 16 | 17 | https://github.com/microsoft/InclusivenessAnalyzerVisualStudio 18 | false 19 | Inclusiveness Analyzer is Roslyn analyzer that checks your code for non-inclusive terms and suggests alternative terms. 20 | As humans, we hold many unconscious and implicit biases that we rely on to react quickly to our environment and any novel stimuli. However, since the unconscious brain processes and reacts with speed, we sometimes speak quickly without thinking, which may cause us to slip offensive terms and stereotypes although we mean no malice. In order to confront these biases that we see in ourselves and others, we must rewire ourselves to regularly use inclusive practices (such as the words we speak). If you don't intentionally and proactively include, you will unintentionally exclude. Join our effort to push out exclusive terms and make inclusive terms a part of our everyday vocabulary! 21 | 22 | Updated word list. 23 | Copyright 24 | InclusivenessAnalyzer, analyzers 25 | true 26 | 27 | $(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput 28 | 29 | Inclusiveness Analyzer 30 | 31 | Microsoft 32 | 33 | 34 | 35 | icon.png 36 | 37 | LICENSE 38 | 39 | 1.3.0 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | True 51 | 52 | 53 | 54 | True 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Package/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/InclusivenessAnalyzerVisualStudio/c9449dc604f453211877e61beaae5e187a74f5b2/src/InclusivenessAnalyzer/InclusivenessAnalyzer.Package/icon.png -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Package/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | if($project.Object.SupportsPackageDependencyResolution) 4 | { 5 | if($project.Object.SupportsPackageDependencyResolution()) 6 | { 7 | # Do not install analyzers via install.ps1, instead let the project system handle it. 8 | return 9 | } 10 | } 11 | 12 | $analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve 13 | 14 | foreach($analyzersPath in $analyzersPaths) 15 | { 16 | if (Test-Path $analyzersPath) 17 | { 18 | # Install the language agnostic analyzers. 19 | foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll) 20 | { 21 | if($project.Object.AnalyzerReferences) 22 | { 23 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName) 24 | } 25 | } 26 | } 27 | } 28 | 29 | # $project.Type gives the language name like (C# or VB.NET) 30 | $languageFolder = "" 31 | if($project.Type -eq "C#") 32 | { 33 | $languageFolder = "cs" 34 | } 35 | if($project.Type -eq "VB.NET") 36 | { 37 | $languageFolder = "vb" 38 | } 39 | if($languageFolder -eq "") 40 | { 41 | return 42 | } 43 | 44 | foreach($analyzersPath in $analyzersPaths) 45 | { 46 | # Install language specific analyzers. 47 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder 48 | if (Test-Path $languageAnalyzersPath) 49 | { 50 | foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll) 51 | { 52 | if($project.Object.AnalyzerReferences) 53 | { 54 | $project.Object.AnalyzerReferences.Add($analyzerFilePath.FullName) 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Package/tools/uninstall.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | if($project.Object.SupportsPackageDependencyResolution) 4 | { 5 | if($project.Object.SupportsPackageDependencyResolution()) 6 | { 7 | # Do not uninstall analyzers via uninstall.ps1, instead let the project system handle it. 8 | return 9 | } 10 | } 11 | 12 | $analyzersPaths = Join-Path (Join-Path (Split-Path -Path $toolsPath -Parent) "analyzers") * -Resolve 13 | 14 | foreach($analyzersPath in $analyzersPaths) 15 | { 16 | # Uninstall the language agnostic analyzers. 17 | if (Test-Path $analyzersPath) 18 | { 19 | foreach ($analyzerFilePath in Get-ChildItem -Path "$analyzersPath\*.dll" -Exclude *.resources.dll) 20 | { 21 | if($project.Object.AnalyzerReferences) 22 | { 23 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName) 24 | } 25 | } 26 | } 27 | } 28 | 29 | # $project.Type gives the language name like (C# or VB.NET) 30 | $languageFolder = "" 31 | if($project.Type -eq "C#") 32 | { 33 | $languageFolder = "cs" 34 | } 35 | if($project.Type -eq "VB.NET") 36 | { 37 | $languageFolder = "vb" 38 | } 39 | if($languageFolder -eq "") 40 | { 41 | return 42 | } 43 | 44 | foreach($analyzersPath in $analyzersPaths) 45 | { 46 | # Uninstall language specific analyzers. 47 | $languageAnalyzersPath = join-path $analyzersPath $languageFolder 48 | if (Test-Path $languageAnalyzersPath) 49 | { 50 | foreach ($analyzerFilePath in Get-ChildItem -Path "$languageAnalyzersPath\*.dll" -Exclude *.resources.dll) 51 | { 52 | if($project.Object.AnalyzerReferences) 53 | { 54 | try 55 | { 56 | $project.Object.AnalyzerReferences.Remove($analyzerFilePath.FullName) 57 | } 58 | catch 59 | { 60 | 61 | } 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/InclusivenessAnalyzer.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0 5 | 6 | true 7 | true 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/InclusivenessAnalyzerUnitTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.Testing; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Threading.Tasks; 4 | using VerifyCS = InclusivenessAnalyzer.Test.CSharpCodeFixVerifier< 5 | InclusivenessAnalyzer.InclusivenessAnalyzer, 6 | InclusivenessAnalyzer.InclusivenessAnalyzerCodeFixProvider>; 7 | 8 | namespace InclusivenessAnalyzer.Test 9 | { 10 | [TestClass] 11 | public class InclusivenessAnalyzerUnitTest 12 | { 13 | 14 | //No diagnostics expected to show up 15 | [TestMethod] 16 | public async Task EmptyTest() 17 | { 18 | var test = @""; 19 | 20 | await VerifyCS.VerifyAnalyzerAsync(test); 21 | } 22 | 23 | [TestMethod] 24 | public async Task ShortWordTest() 25 | { 26 | var test = @"class check {}"; 27 | 28 | await VerifyCS.VerifyAnalyzerAsync(test); 29 | } 30 | 31 | [TestMethod] 32 | public async Task ShortWordHeTest() 33 | { 34 | var test = @"class he {}"; 35 | 36 | var expected = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(1, 7).WithArguments("he", "they"); 37 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 38 | } 39 | 40 | //Diagnostic and CodeFix both triggered and checked for 41 | [TestMethod] 42 | public async Task WhitelistTypeNameTest() 43 | { 44 | var test = @" 45 | using System; 46 | using System.Collections.Generic; 47 | using System.Linq; 48 | using System.Text; 49 | using System.Threading.Tasks; 50 | using System.Diagnostics; 51 | 52 | namespace ConsoleApplication1 53 | { 54 | class WhiteList 55 | { 56 | } 57 | }"; 58 | 59 | var expected = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(11,15).WithArguments("WhiteList", "allow list, access list, permit"); 60 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 61 | } 62 | 63 | [TestMethod] 64 | public async Task WhitelistMethodNameTest() 65 | { 66 | var test = @" 67 | using System; 68 | using System.Collections.Generic; 69 | using System.Linq; 70 | using System.Text; 71 | using System.Threading.Tasks; 72 | using System.Diagnostics; 73 | 74 | namespace ConsoleApplication1 75 | { 76 | class Program 77 | { 78 | public void WhiteList() { } 79 | } 80 | }"; 81 | 82 | var expected = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(13, 25).WithArguments("WhiteList", "allow list, access list, permit"); 83 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 84 | } 85 | 86 | [TestMethod] 87 | public async Task WhitelistParameterTest() 88 | { 89 | var test = @" 90 | using System; 91 | using System.Collections.Generic; 92 | using System.Linq; 93 | using System.Text; 94 | using System.Threading.Tasks; 95 | using System.Diagnostics; 96 | 97 | namespace ConsoleApplication1 98 | { 99 | class Program 100 | { 101 | public void DoWork(string whiteList) { } 102 | } 103 | }"; 104 | 105 | var expected = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(13, 39).WithArguments("whiteList", "allow list, access list, permit"); 106 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 107 | } 108 | 109 | [TestMethod] 110 | public async Task BlacklistPropertyTest() 111 | { 112 | var test = @" 113 | using System; 114 | using System.Collections.Generic; 115 | using System.Linq; 116 | using System.Text; 117 | using System.Threading.Tasks; 118 | using System.Diagnostics; 119 | 120 | namespace ConsoleApplication1 121 | { 122 | class Program 123 | { 124 | public int BlacklistNumber { get; set; } 125 | } 126 | }"; 127 | 128 | var expected1 = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(13, 24).WithArguments("BlacklistNumber", "deny list, blocklist, exclude list"); 129 | var expected2 = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(13, 42).WithArguments("get_BlacklistNumber", "deny list, blocklist, exclude list"); 130 | var expected3 = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(13, 47).WithArguments("set_BlacklistNumber", "deny list, blocklist, exclude list"); 131 | await VerifyCS.VerifyAnalyzerAsync(test, expected1, expected2, expected3); 132 | } 133 | 134 | [TestMethod] 135 | public async Task BlacklistFieldTest() 136 | { 137 | var test = @" 138 | using System; 139 | using System.Collections.Generic; 140 | using System.Linq; 141 | using System.Text; 142 | using System.Threading.Tasks; 143 | using System.Diagnostics; 144 | 145 | namespace ConsoleApplication1 146 | { 147 | class Program 148 | { 149 | public string BlackListValue; 150 | } 151 | }"; 152 | 153 | var expected = VerifyCS.Diagnostic("Inclusive").WithLocation(13, 27).WithArguments("BlackListValue", "deny list, blocklist, exclude list"); 154 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 155 | } 156 | 157 | [TestMethod] 158 | public async Task BlacklistCommentTest() 159 | { 160 | var test = @" 161 | using System; 162 | using System.Collections.Generic; 163 | using System.Linq; 164 | using System.Text; 165 | using System.Threading.Tasks; 166 | using System.Diagnostics; 167 | 168 | namespace ConsoleApplication1 169 | { 170 | /// 171 | /// blacklist here 172 | /// 173 | class Program 174 | { 175 | public string ListValue; 176 | } 177 | }"; 178 | 179 | var expected = VerifyCS.Diagnostic(InclusivenessAnalyzer.DiagnosticId).WithLocation(11, 12).WithArguments("blacklist", "deny list, blocklist, exclude list"); 180 | await VerifyCS.VerifyAnalyzerAsync(test, expected); 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpAnalyzerVerifier`1+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Testing; 2 | using Microsoft.CodeAnalysis.Diagnostics; 3 | using Microsoft.CodeAnalysis.Testing.Verifiers; 4 | 5 | namespace InclusivenessAnalyzer.Test 6 | { 7 | public static partial class CSharpAnalyzerVerifier 8 | where TAnalyzer : DiagnosticAnalyzer, new() 9 | { 10 | public class Test : CSharpAnalyzerTest 11 | { 12 | public Test() 13 | { 14 | SolutionTransforms.Add((solution, projectId) => 15 | { 16 | var compilationOptions = solution.GetProject(projectId).CompilationOptions; 17 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( 18 | compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); 19 | solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); 20 | 21 | return solution; 22 | }); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpAnalyzerVerifier`1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp.Testing; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using Microsoft.CodeAnalysis.Testing; 5 | using Microsoft.CodeAnalysis.Testing.Verifiers; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace InclusivenessAnalyzer.Test 10 | { 11 | public static partial class CSharpAnalyzerVerifier 12 | where TAnalyzer : DiagnosticAnalyzer, new() 13 | { 14 | /// 15 | public static DiagnosticResult Diagnostic() 16 | => CSharpAnalyzerVerifier.Diagnostic(); 17 | 18 | /// 19 | public static DiagnosticResult Diagnostic(string diagnosticId) 20 | => CSharpAnalyzerVerifier.Diagnostic(diagnosticId); 21 | 22 | /// 23 | public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) 24 | => CSharpAnalyzerVerifier.Diagnostic(descriptor); 25 | 26 | /// 27 | public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) 28 | { 29 | var test = new Test 30 | { 31 | TestCode = source, 32 | }; 33 | 34 | test.ExpectedDiagnostics.AddRange(expected); 35 | await test.RunAsync(CancellationToken.None); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpCodeFixVerifier`2+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeFixes; 2 | using Microsoft.CodeAnalysis.CSharp.Testing; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using Microsoft.CodeAnalysis.Testing.Verifiers; 5 | 6 | namespace InclusivenessAnalyzer.Test 7 | { 8 | public static partial class CSharpCodeFixVerifier 9 | where TAnalyzer : DiagnosticAnalyzer, new() 10 | where TCodeFix : CodeFixProvider, new() 11 | { 12 | public class Test : CSharpCodeFixTest 13 | { 14 | public Test() 15 | { 16 | SolutionTransforms.Add((solution, projectId) => 17 | { 18 | var compilationOptions = solution.GetProject(projectId).CompilationOptions; 19 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( 20 | compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); 21 | solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); 22 | 23 | return solution; 24 | }); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpCodeFixVerifier`2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeFixes; 3 | using Microsoft.CodeAnalysis.CSharp.Testing; 4 | using Microsoft.CodeAnalysis.Diagnostics; 5 | using Microsoft.CodeAnalysis.Testing; 6 | using Microsoft.CodeAnalysis.Testing.Verifiers; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace InclusivenessAnalyzer.Test 11 | { 12 | public static partial class CSharpCodeFixVerifier 13 | where TAnalyzer : DiagnosticAnalyzer, new() 14 | where TCodeFix : CodeFixProvider, new() 15 | { 16 | /// 17 | public static DiagnosticResult Diagnostic() 18 | => CSharpCodeFixVerifier.Diagnostic(); 19 | 20 | /// 21 | public static DiagnosticResult Diagnostic(string diagnosticId) 22 | => CSharpCodeFixVerifier.Diagnostic(diagnosticId); 23 | 24 | /// 25 | public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) 26 | => CSharpCodeFixVerifier.Diagnostic(descriptor); 27 | 28 | /// 29 | public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) 30 | { 31 | var test = new Test 32 | { 33 | TestCode = source, 34 | }; 35 | 36 | test.ExpectedDiagnostics.AddRange(expected); 37 | await test.RunAsync(CancellationToken.None); 38 | } 39 | 40 | /// 41 | public static async Task VerifyCodeFixAsync(string source, string fixedSource) 42 | => await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); 43 | 44 | /// 45 | public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) 46 | => await VerifyCodeFixAsync(source, new[] { expected }, fixedSource); 47 | 48 | /// 49 | public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) 50 | { 51 | var test = new Test 52 | { 53 | TestCode = source, 54 | FixedCode = fixedSource, 55 | }; 56 | 57 | test.ExpectedDiagnostics.AddRange(expected); 58 | await test.RunAsync(CancellationToken.None); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpCodeRefactoringVerifier`1+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeRefactorings; 2 | using Microsoft.CodeAnalysis.CSharp.Testing; 3 | using Microsoft.CodeAnalysis.Testing.Verifiers; 4 | 5 | namespace InclusivenessAnalyzer.Test 6 | { 7 | public static partial class CSharpCodeRefactoringVerifier 8 | where TCodeRefactoring : CodeRefactoringProvider, new() 9 | { 10 | public class Test : CSharpCodeRefactoringTest 11 | { 12 | public Test() 13 | { 14 | SolutionTransforms.Add((solution, projectId) => 15 | { 16 | var compilationOptions = solution.GetProject(projectId).CompilationOptions; 17 | compilationOptions = compilationOptions.WithSpecificDiagnosticOptions( 18 | compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings)); 19 | solution = solution.WithProjectCompilationOptions(projectId, compilationOptions); 20 | 21 | return solution; 22 | }); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpCodeRefactoringVerifier`1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeRefactorings; 2 | using Microsoft.CodeAnalysis.Testing; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace InclusivenessAnalyzer.Test 7 | { 8 | public static partial class CSharpCodeRefactoringVerifier 9 | where TCodeRefactoring : CodeRefactoringProvider, new() 10 | { 11 | /// 12 | public static async Task VerifyRefactoringAsync(string source, string fixedSource) 13 | { 14 | await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); 15 | } 16 | 17 | /// 18 | public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) 19 | { 20 | await VerifyRefactoringAsync(source, new[] { expected }, fixedSource); 21 | } 22 | 23 | /// 24 | public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) 25 | { 26 | var test = new Test 27 | { 28 | TestCode = source, 29 | FixedCode = fixedSource, 30 | }; 31 | 32 | test.ExpectedDiagnostics.AddRange(expected); 33 | await test.RunAsync(CancellationToken.None); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/CSharpVerifierHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using System; 4 | using System.Collections.Immutable; 5 | 6 | namespace InclusivenessAnalyzer.Test 7 | { 8 | internal static class CSharpVerifierHelper 9 | { 10 | /// 11 | /// By default, the compiler reports diagnostics for nullable reference types at 12 | /// , and the analyzer test framework defaults to only validating 13 | /// diagnostics at . This map contains all compiler diagnostic IDs 14 | /// related to nullability mapped to , which is then used to enable all 15 | /// of these warnings for default validation during analyzer and code fix tests. 16 | /// 17 | internal static ImmutableDictionary NullableWarnings { get; } = GetNullableWarningsFromCompiler(); 18 | 19 | private static ImmutableDictionary GetNullableWarningsFromCompiler() 20 | { 21 | string[] args = { "/warnaserror:nullable" }; 22 | var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory); 23 | var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions; 24 | 25 | // Workaround for https://github.com/dotnet/roslyn/issues/41610 26 | nullableWarnings = nullableWarnings 27 | .SetItem("CS8632", ReportDiagnostic.Error) 28 | .SetItem("CS8669", ReportDiagnostic.Error); 29 | 30 | return nullableWarnings; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicAnalyzerVerifier`1+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.Diagnostics; 2 | using Microsoft.CodeAnalysis.Testing.Verifiers; 3 | using Microsoft.CodeAnalysis.VisualBasic.Testing; 4 | 5 | namespace InclusivenessAnalyzer.Test 6 | { 7 | public static partial class VisualBasicAnalyzerVerifier 8 | where TAnalyzer : DiagnosticAnalyzer, new() 9 | { 10 | public class Test : VisualBasicAnalyzerTest 11 | { 12 | public Test() 13 | { 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicAnalyzerVerifier`1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.Diagnostics; 3 | using Microsoft.CodeAnalysis.Testing; 4 | using Microsoft.CodeAnalysis.Testing.Verifiers; 5 | using Microsoft.CodeAnalysis.VisualBasic.Testing; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace InclusivenessAnalyzer.Test 10 | { 11 | public static partial class VisualBasicAnalyzerVerifier 12 | where TAnalyzer : DiagnosticAnalyzer, new() 13 | { 14 | /// 15 | public static DiagnosticResult Diagnostic() 16 | => VisualBasicAnalyzerVerifier.Diagnostic(); 17 | 18 | /// 19 | public static DiagnosticResult Diagnostic(string diagnosticId) 20 | => VisualBasicAnalyzerVerifier.Diagnostic(diagnosticId); 21 | 22 | /// 23 | public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) 24 | => VisualBasicAnalyzerVerifier.Diagnostic(descriptor); 25 | 26 | /// 27 | public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) 28 | { 29 | var test = new Test 30 | { 31 | TestCode = source, 32 | }; 33 | 34 | test.ExpectedDiagnostics.AddRange(expected); 35 | await test.RunAsync(CancellationToken.None); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicCodeFixVerifier`2+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeFixes; 2 | using Microsoft.CodeAnalysis.Diagnostics; 3 | using Microsoft.CodeAnalysis.Testing.Verifiers; 4 | using Microsoft.CodeAnalysis.VisualBasic.Testing; 5 | 6 | namespace InclusivenessAnalyzer.Test 7 | { 8 | public static partial class VisualBasicCodeFixVerifier 9 | where TAnalyzer : DiagnosticAnalyzer, new() 10 | where TCodeFix : CodeFixProvider, new() 11 | { 12 | public class Test : VisualBasicCodeFixTest 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicCodeFixVerifier`2.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeFixes; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using Microsoft.CodeAnalysis.Testing; 5 | using Microsoft.CodeAnalysis.Testing.Verifiers; 6 | using Microsoft.CodeAnalysis.VisualBasic.Testing; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | 10 | namespace InclusivenessAnalyzer.Test 11 | { 12 | public static partial class VisualBasicCodeFixVerifier 13 | where TAnalyzer : DiagnosticAnalyzer, new() 14 | where TCodeFix : CodeFixProvider, new() 15 | { 16 | /// 17 | public static DiagnosticResult Diagnostic() 18 | => VisualBasicCodeFixVerifier.Diagnostic(); 19 | 20 | /// 21 | public static DiagnosticResult Diagnostic(string diagnosticId) 22 | => VisualBasicCodeFixVerifier.Diagnostic(diagnosticId); 23 | 24 | /// 25 | public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) 26 | => VisualBasicCodeFixVerifier.Diagnostic(descriptor); 27 | 28 | /// 29 | public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected) 30 | { 31 | var test = new Test 32 | { 33 | TestCode = source, 34 | }; 35 | 36 | test.ExpectedDiagnostics.AddRange(expected); 37 | await test.RunAsync(CancellationToken.None); 38 | } 39 | 40 | /// 41 | public static async Task VerifyCodeFixAsync(string source, string fixedSource) 42 | => await VerifyCodeFixAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); 43 | 44 | /// 45 | public static async Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource) 46 | => await VerifyCodeFixAsync(source, new[] { expected }, fixedSource); 47 | 48 | /// 49 | public static async Task VerifyCodeFixAsync(string source, DiagnosticResult[] expected, string fixedSource) 50 | { 51 | var test = new Test 52 | { 53 | TestCode = source, 54 | FixedCode = fixedSource, 55 | }; 56 | 57 | test.ExpectedDiagnostics.AddRange(expected); 58 | await test.RunAsync(CancellationToken.None); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicCodeRefactoringVerifier`1+Test.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeRefactorings; 2 | using Microsoft.CodeAnalysis.Testing.Verifiers; 3 | using Microsoft.CodeAnalysis.VisualBasic.Testing; 4 | 5 | namespace InclusivenessAnalyzer.Test 6 | { 7 | public static partial class VisualBasicCodeRefactoringVerifier 8 | where TCodeRefactoring : CodeRefactoringProvider, new() 9 | { 10 | public class Test : VisualBasicCodeRefactoringTest 11 | { 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Test/Verifiers/VisualBasicCodeRefactoringVerifier`1.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CodeRefactorings; 2 | using Microsoft.CodeAnalysis.Testing; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | 6 | namespace InclusivenessAnalyzer.Test 7 | { 8 | public static partial class VisualBasicCodeRefactoringVerifier 9 | where TCodeRefactoring : CodeRefactoringProvider, new() 10 | { 11 | /// 12 | public static async Task VerifyRefactoringAsync(string source, string fixedSource) 13 | { 14 | await VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, fixedSource); 15 | } 16 | 17 | /// 18 | public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource) 19 | { 20 | await VerifyRefactoringAsync(source, new[] { expected }, fixedSource); 21 | } 22 | 23 | /// 24 | public static async Task VerifyRefactoringAsync(string source, DiagnosticResult[] expected, string fixedSource) 25 | { 26 | var test = new Test 27 | { 28 | TestCode = source, 29 | FixedCode = fixedSource, 30 | }; 31 | 32 | test.ExpectedDiagnostics.AddRange(expected); 33 | await test.RunAsync(CancellationToken.None); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Vsix/InclusivenessAnalyzer.Vsix.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | net472 7 | InclusivenessAnalyzer.Vsix 8 | InclusivenessAnalyzer.Vsix 9 | 10 | 11 | 12 | false 13 | false 14 | false 15 | false 16 | false 17 | false 18 | Roslyn 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Program 27 | $(DevEnvDir)devenv.exe 28 | /rootsuffix $(VSSDKTargetPlatformRegRootSuffix) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Vsix/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Inclusiveness Analyzer 6 | This Roslyn analyzer checks your code for non-inclusive words and suggests alternate words that are inclusive. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Vsix2022/InclusivenessAnalyzer.Vsix2022.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | net472 7 | InclusivenessAnalyzer.Vsix 8 | InclusivenessAnalyzer2022.Vsix 9 | 10 | 11 | 12 | false 13 | false 14 | false 15 | false 16 | false 17 | false 18 | Roslyn 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Program 27 | $(DevEnvDir)devenv.exe 28 | /rootsuffix $(VSSDKTargetPlatformRegRootSuffix) 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer.Vsix2022/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Inclusiveness Analyzer VS2022 6 | This Roslyn analyzer checks your code for non-inclusive words and suggests alternate words that are inclusive. 7 | 8 | 9 | 10 | amd64 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer/InclusivenessAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | using Microsoft.CodeAnalysis.Diagnostics; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Collections.Immutable; 8 | using System.Linq; 9 | 10 | namespace InclusivenessAnalyzer 11 | { 12 | [DiagnosticAnalyzer(LanguageNames.CSharp)] 13 | public class InclusivenessAnalyzer : DiagnosticAnalyzer 14 | { 15 | public const string DiagnosticId = "Inclusive"; 16 | private static readonly Dictionary InclusiveTerms = new Dictionary() { 17 | {"whitelist", "allow list, access list, permit" }, 18 | {"white list", "allow list, access list, permit" }, 19 | {"blacklist", "deny list, blocklist, exclude list" }, 20 | {"black list", "deny list, blocklist, exclude list" }, 21 | {"master", "primary, main, default, leader" }, 22 | {"slave", "replica, standby, secondary, follower" }, 23 | {"minority", "marginalized groups, underrepresented groups, people of color" }, 24 | {"minorities", "marginalized groups, underrepresented groups, people of color" }, 25 | {"brownbag", "learning session, lunch-and-learn, sack lunch" }, 26 | {"brown bag", "learning session, lunch-and-learn, sack lunch" }, 27 | {"white box", "open-box" }, 28 | {"white-box", "open-box" }, 29 | {"black box", "closed-box" }, 30 | {"black-box", "closed-box" }, 31 | {"culture fit", "values fit, cultural contribution" }, 32 | {"citizen", "resident, people" }, 33 | {"guys", "folks, you all, y'all, people, teammates, team" }, 34 | {"he", "they" }, 35 | {"his", "their, theirs" }, 36 | {"him", "them" }, 37 | {"she", "they" }, 38 | {"her", "their" }, 39 | {"hers", "theirs" }, 40 | {"manpower", "human effort, person hours, engineer hours, work, workforce, personnel, team, workers" }, 41 | {"man hours", "human effort, person hours, engineer hours, work, workforce, personnel, team, workers" }, 42 | {"mankind", "people, humanity" }, 43 | {"chairman", "chairperson, spokesperson, moderator, discussion leader, chair" }, 44 | {"foreman", "chairperson, spokesperson, moderator, discussion leader, chair" }, 45 | {"middleman", "middle person, intermediary, agent, dealer" }, 46 | {"mother", "parent, caretaker, nurturer, guardian" }, 47 | {"mothering", "parenting, caretaking, caring, nurturing" }, 48 | {"father", "parent, caretaker, nurturer, guardian" }, 49 | {"fathering", "parenting, caretaking, caring, nurturing" }, 50 | {"wife", "spouse, partner, significant other" }, 51 | {"husband", "spouse, partner, significant other" }, 52 | {"boyfriend", "partner, significant other" }, 53 | {"girlfriend", "partner, significant other" }, 54 | {"girl", "woman" }, 55 | {"girls", "women" }, 56 | {"female", "woman" }, 57 | {"females", "women" }, 58 | {"boy", "man" }, 59 | {"boys", "men" }, 60 | {"male", "man" }, 61 | {"males", "men" }, 62 | {"mom test", "user test" }, 63 | {"girlfriend test", "user test" }, 64 | {"ninja", "professional" }, 65 | {"rockstar", "professional" }, 66 | {"housekeeping", "maintenance, cleanup, preparation" }, 67 | {"opposite sex", "different sex" }, 68 | {"grandfathered in", "exempt" }, 69 | {"grandfathered", "exempt" }, 70 | {"midget", "little person, short stature, person with dwarfism" }, 71 | {"crazy", "unexpected, unpredictable, surprising" }, 72 | {"insane", "unexpected, unpredictable, surprising" }, 73 | {"freak", "unexpected, unpredictable, surprising" }, 74 | {"tone deaf", "oblivious" }, 75 | {"blind spot", "dead spot, unseen area" }, 76 | {"OCD", "organized, detail-oriented" }, 77 | {"depressed", "sad, upset" }, 78 | {"depressing", "saddening, upsetting" }, 79 | {"handicap", "person with a disability" }, 80 | {"cripple", "person with a disability" }, 81 | {"sanity check", "quick check, confidence check, coherence check" }, 82 | {"sane", "correct, adequate, sufficient, valid, sensible, coherent" }, 83 | {"retard", "person with disabilities, mentally limited" }, 84 | {"dummy value", "placeholder value, sample value, design value" } 85 | }; 86 | 87 | private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources)); 88 | private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); 89 | private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources)); 90 | private const string HelpLinkUri = "https://github.com/merill/InclusivenessAnalyzer/"; 91 | private const string Category = "Microsoft.Inclusive"; 92 | 93 | private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description, helpLinkUri: HelpLinkUri); 94 | 95 | public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } } 96 | 97 | public override void Initialize(AnalysisContext context) 98 | { 99 | try 100 | { 101 | context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); 102 | context.EnableConcurrentExecution(); 103 | 104 | context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType, SymbolKind.Method, SymbolKind.Property, SymbolKind.Field, 105 | SymbolKind.Event, SymbolKind.Namespace, SymbolKind.Parameter); 106 | 107 | context.RegisterSyntaxNodeAction(CheckComments, SyntaxKind.VariableDeclaration, SyntaxKind.CatchDeclaration, SyntaxKind.NamespaceDeclaration, 108 | SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration, SyntaxKind.InterfaceDeclaration, SyntaxKind.EnumDeclaration, SyntaxKind.DelegateDeclaration, 109 | SyntaxKind.EnumMemberDeclaration, SyntaxKind.FieldDeclaration, SyntaxKind.EventFieldDeclaration, SyntaxKind.MethodDeclaration, SyntaxKind.OperatorDeclaration, 110 | SyntaxKind.ConversionOperatorDeclaration, SyntaxKind.ConstructorDeclaration, SyntaxKind.DestructorDeclaration, SyntaxKind.PropertyDeclaration, 111 | SyntaxKind.EventDeclaration, SyntaxKind.IndexerDeclaration, SyntaxKind.GetAccessorDeclaration, SyntaxKind.SetAccessorDeclaration, 112 | SyntaxKind.AddAccessorDeclaration, SyntaxKind.RemoveAccessorDeclaration, SyntaxKind.UnknownAccessorDeclaration); 113 | } 114 | catch { } 115 | } 116 | 117 | private static void AnalyzeSymbol(SymbolAnalysisContext context) 118 | { 119 | try 120 | { 121 | var symbol = context.Symbol; 122 | 123 | // Find just those named type symbols with non-inclusive terms. 124 | foreach (KeyValuePair entry in InclusiveTerms) 125 | { 126 | if (IsMatch(symbol.Name, entry.Key)) 127 | { 128 | // For all such symbols, produce a diagnostic. 129 | var diagnostic = Diagnostic.Create(Rule, symbol.Locations[0], symbol.Name, entry.Value); 130 | 131 | context.ReportDiagnostic(diagnostic); 132 | break; 133 | } 134 | } 135 | } 136 | catch { } 137 | } 138 | 139 | /// 140 | /// Checks if term was found in the symbol. 141 | /// Match whole word if it has less than 5 characters 142 | /// 143 | /// The phrase that is being checked. 144 | /// The non-inclusive phrase we are looking for. 145 | /// 146 | private static bool IsMatch(string symbol, string term) 147 | { 148 | return term.Length < 5 ? 149 | symbol.Equals(term, StringComparison.InvariantCultureIgnoreCase) : 150 | symbol.IndexOf(term, StringComparison.InvariantCultureIgnoreCase) >= 0; 151 | 152 | } 153 | 154 | private void CheckComments(SyntaxNodeAnalysisContext context) 155 | { 156 | try 157 | { 158 | var node = context.Node; 159 | 160 | var xmlTrivia = node.GetLeadingTrivia() 161 | .Select(i => i.GetStructure()) 162 | .OfType() 163 | .FirstOrDefault(); 164 | 165 | if (xmlTrivia == null) return; 166 | 167 | var content = xmlTrivia.ToFullString(); 168 | foreach (KeyValuePair entry in InclusiveTerms) 169 | { 170 | if (IsMatch(content, entry.Key)) 171 | { 172 | // For all such symbols, produce a diagnostic. 173 | var diagnostic = Diagnostic.Create(Rule, xmlTrivia.GetLocation(), entry.Key, entry.Value); 174 | 175 | context.ReportDiagnostic(diagnostic); 176 | break; 177 | } 178 | } 179 | } 180 | catch { } 181 | } 182 | } 183 | } -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer/InclusivenessAnalyzer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | false 6 | 7 | 8 | *$(MSBuildProjectFullPath)* 9 | 1.3.0 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace InclusivenessAnalyzer { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("InclusivenessAnalyzer.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Using inclusive terms makes our code better and shows we care ❤.. 65 | /// 66 | internal static string AnalyzerDescription { 67 | get { 68 | return ResourceManager.GetString("AnalyzerDescription", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to The phrase '{0}' is not inclusive. Try using an alternative word like '{1}'. 74 | /// 75 | internal static string AnalyzerMessageFormat { 76 | get { 77 | return ResourceManager.GetString("AnalyzerMessageFormat", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to Use inclusive words. 83 | /// 84 | internal static string AnalyzerTitle { 85 | get { 86 | return ResourceManager.GetString("AnalyzerTitle", resourceCulture); 87 | } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/InclusivenessAnalyzer/InclusivenessAnalyzer/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Using inclusive terms makes our code better and shows we care ❤. 122 | An optional longer localizable description of the diagnostic. 123 | 124 | 125 | The phrase '{0}' is not inclusive. Try using an alternative word like '{1}' 126 | The format-able message the diagnostic displays. 127 | 128 | 129 | Use inclusive words 130 | The title of the diagnostic. 131 | 132 | -------------------------------------------------------------------------------- /src/NuGet.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /terms.md: -------------------------------------------------------------------------------- 1 | ## **Below you'll find a list of exclusive terms, inclusive term alternatives, explanations, and links.** 2 | ### Please be aware that these terms have a varying level of offense and may depend on the context in which the term is used. 3 | #### Help us grow this list! 4 | 5 | - whitelist
6 | **Alternative**: allow list, access list, permit
7 | **Category**: Diversity
8 | **Context**: Do not use the term "white list" (or "whitelist"), because there may be a perceived association with racial bias. Use alternate terms that do not perpetuate the stereotype of "black" as negative and "white" as positive.
9 | **Link**: https://en.wikipedia.org/wiki/Whitelisting
10 | 11 | - blacklist
12 | **Alternative**: deny list, deny, blocklist, exclude list
13 | **Category**: Diversity
14 | **Context**: Do not use the term "black list" (or "blacklist"), because there may be a perceived association with racial bias. Use alternate terms that do not perpetuate the stereotype of "black" as negative and "white" as positive.
15 | **Link**: https://en.wikipedia.org/wiki/Blacklist_(computing)
16 | 17 | - master
18 | **Alternative**: primary, main, default, leader
19 | **Category**: Diversity
20 | **Context**: Do not use master/slave in new code or content as this may be considered offensive language. It alludes to dominant practices and values that have perceived association with racial bias.
21 | **Link**: https://en.wikipedia.org/wiki/Master/slave_(technology)
22 | 23 | - slave
24 | **Alternative**: replica, standby, secondary, follower
25 | **Category**: Diversity
26 | **Context**: Do not use master/slave in new code or content as this may be considered offensive language. It alludes to dominant practices and values that have perceived association with racial bias.
27 | **Link**: https://en.wikipedia.org/wiki/Master/slave_(technology)
28 | 29 | - minority, minorities
30 | **Alternative**: marginalized groups, underrepresented groups, people of color
31 | **Category**: Diversity
32 | **Context**: Avoid using "minority" since the term does not include all marginalized groups. To refer to non-White racial and ethnic groups collectively, use terms such as “people of color” or “underrepresented groups” instead. The use of “minority” may be viewed pejoratively because it is usually equated with being less than, oppressed, or deficient in comparison with the majority.
33 | **Link**: https://apastyle.apa.org/style-grammar-guidelines/bias-free-language/racial-ethnic-minorities
34 | 35 | - brownbag, brown bag
36 | **Alternative**: learning session, lunch-and-learn, sack lunch
37 | **Category**: Diversity
38 | **Context**: Avoid language that may trigger historical stereotypes. Historically, 'brown bag' was used to determine if a person's skin color was light enough to allow admission to an event, a home, etc. Note: The connotation is associated with the phrase 'brown bag' rather than the color brown itself.
39 | **Link**: https://www.nbcnews.com/news/us-news/theres-more-seattle-brown-bag-racial-controversy-meets-eye-flna6C10836263
40 | 41 | - white box, white-box
42 | **Alternative**: open-box
43 | **Category**: Diversity
44 | **Context**: "Open box" provides a more practical description and illustration of this software testing discipline as well as an intentional departure from the racial connotations of "white box" and "black box" terminology. It decouples the exclusive and advanced knowledge characterized by testers from the term "white".
45 | **Link**: https://en.wikipedia.org/wiki/White-box_testing
46 | 47 | - black box, black-box
48 | **Alternative**: closed-box
49 | **Category**: Diversity
50 | **Context**: "Closed box" provides a more practical description and illustration of this software testing discipline as well as an intentional departure from the racial connotations of "white box" and "black box" terminology. It decouples the lack of knowledge of the system characterized by testers from the term "black".
51 | **Link**: https://en.wikipedia.org/wiki/Black-box_testing
52 | 53 | - culture fit
54 | **Alternative**: values fit, cultural contribution
55 | **Category**: Inclusion
56 | **Context**: Avoid terms and practices that can lead to strict conformance to a dominant and accepted culture. Culture fit is used to support an improper or discriminatory motivation aimed at prejudicing those in a, or several, protected classes.
57 | **Link**: https://buffer.com/resources/culture-fit/
58 | https://www.hrdive.com/news/is-culture-fit-code-for-bias-recruiters-must-be-wary-experts-say/507272/
59 | 60 | - citizen
61 | **Alternative**: resident, people
62 | **Category**: Inclusion
63 | **Context**: Be aware that not everyone is a citizen of the country they live in, so it is not appropriate in all contexts. Only use this term if you intend to refer specifically to a "citizen."
64 | **Link**: https://content-guide.18f.gov/our-style/inclusive-language/
65 | 66 | - guys
67 | **Alternative**: folks, you all, y'all, people, teammates, team
68 | **Category**: Gendered term
69 | **Context**: Avoid the gendered term "guys" when broadly referring to people that are not male. Utilize gender neutral communications to make all parties feel included and allow space for all identities.
70 | **Link**: https://www.huffpost.com/entry/gendered-language-hey-guys_l_5f21b189c5b6b8cd63b0f331
71 | 72 | - he/his/him, she/hers/her
73 | **Alternative**: they/their(s)/them
74 | **Category**: Gendered term
75 | **Context**: Avoid gendered terms especially when assuming pronouns. Unless you know the individual's pronouns, utilize gender neutral communications allow space for all identities.
76 | **Link**: https://developers.google.com/style/pronouns#gender-neutral-pronouns
77 | https://www.merriam-webster.com/dictionary/they
78 | https://www.englishgrammar.org/words-heshe-himher-hishers/
79 | 80 | - manpower, man hours
81 | **Alternative**: human effort, person hours, engineer hours, work, workforce, personnel, team, workers
82 | **Category**: Gendered term
83 | **Context**: Utilize gender neutral communications whenever possible. In general, avoid gendered terms to make all parties feel included and allow space for all identities.
84 | **Link**: https://www.bbc.com/news/world-us-canada-49036816
85 | 86 | - mankind
87 | **Alternative**: people, humanity
88 | **Category**: Gendered term
89 | **Context**: Utilize gender neutral communications whenever possible. In general, avoid gendered terms to make all parties feel included and allow space for all identities.
90 | **Link**: https://wmich.edu/writing/genderbias
91 | 92 | - chairman, foreman
93 | **Alternative**: chairperson, spokesperson, moderator, discussion leader, chair
94 | **Category**: Gendered term
95 | **Context**: Utilize gender neutral communications whenever possible. In general, avoid gendered terms to make all parties feel included and allow space for all identities.
96 | **Link**: https://wmich.edu/writing/genderbias
97 | 98 | - middleman
99 | **Alternative**: middle person, intermediary, agent, dealer
100 | **Category**: Gendered term
101 | **Context**: Utilize gender neutral communications whenever possible. In general, avoid gendered terms to make all parties feel included and allow space for all identities.
102 | **Link**: https://wmich.edu/writing/genderbias
103 | 104 | - mother, father
105 | **Alternative**: parent, caretaker, nurturer, guardian
106 | **Category**: Gendered term
107 | **Context**: Avoid gendered terms especially when assuming pronouns. Unless you know the individual's pronouns, utilize gender neutral communications allow space for all identities.
108 | **Link**: https://wmich.edu/writing/genderbias
109 | 110 | - mothering, fathering
111 | **Alternative**: parenting, caretaking, caring, nurturing
112 | **Category**: Gendered term
113 | **Context**: Avoid gendered terms especially when assuming pronouns. Unless you know the individual's pronouns, utilize gender neutral communications allow space for all identities.
114 | **Link**: https://wmich.edu/writing/genderbias
115 | 116 | - wife, husband
117 | **Alternative**: spouse, partner, significant other
118 | **Category**: Gendered term
119 | **Context**: Avoid gendered terms especially when assuming pronouns. Unless you know the individual's pronouns, utilize gender neutral communications allow space for all identities.
120 | **Link**: https://www.forbes.com/sites/kimelsesser/2020/07/08/how-to-use-gender-neutral-language-and-why-its-important-to-try/?sh=2ed89a8326ba
121 | 122 | - boyfriend, girlfriend
123 | **Alternative**: partner, significant other
124 | **Category**: Gendered term
125 | **Context**: Avoid gendered terms especially when assuming pronouns. Unless you know the individual's pronouns, utilize gender neutral communications allow space for all identities.
126 | **Link**: https://www.forbes.com/sites/kimelsesser/2020/07/08/how-to-use-gender-neutral-language-and-why-its-important-to-try/?sh=2ed89a8326ba
127 | 128 | - girl(s), boy(s)
129 | **Alternative**: woman/women, man/men
130 | **Category**: Gendered term, Ageism
131 | **Context**: Avoid using "girl" or "boy" when being used to describe an individual 18 years or over, as it can be belittling. Use "woman" or "man" instead.
132 | **Link**: https://www.theguardian.com/commentisfree/2014/may/27/is-the-word-girl-offensive
133 | 134 | - female, male
135 | **Alternative**: woman/women, man/men
136 | **Category**: Gendered term
137 | **Context**: Avoid using "female" or "male" as it scientifically reduces a woman or man to their reproductive capabilities, rather than their identity. Use "woman" or "man" instead.
138 | **Link**: https://lawprofessors.typepad.com/gender_law/2017/11/why-you-should-stop-using-the-word-female-.html
139 | 140 | - mom test
141 | **Alternative**: user test
142 | **Category**: Gendered term
143 | **Context**: Avoid using "mom test" which has sexist and ageist connotations. The term has been used to describe putting a product in front of unfamiliar visitors to learn more how they would use it. The assumption is that if such a person can use a program, anyone can.
144 | **Link**: https://geekfeminism.wikia.org/wiki/So_simple,_your_mother_could_do_it
145 | https://content-guide.18f.gov/our-style/inclusive-language/
146 | https://buffer.com/resources/inclusive-language-tech/
147 | 148 | - girlfriend test
149 | **Alternative**: user test
150 | **Category**: Gendered term
151 | **Context**: Avoid using "girlfriend test" which have sexist connotations. The term has been used to describe putting a product in front of unfamiliar visitors to learn more how they would use it. The assumption is that if such a person can use a program, anyone can.
152 | **Link**: https://content-guide.18f.gov/our-style/inclusive-language/
153 | https://buffer.com/resources/inclusive-language-tech/
154 | 155 | - ninja
156 | **Alternative**: professional
157 | **Category**: Gendered term
158 | **Context**: Avoid since it is skewed to a particular gender.
159 | **Link**: https://learn.joinhandshake.com/employers/70-inclusive-language-principles-that-will-make-you-a-more-successful-recruiter/
160 | 161 | - rockstar
162 | **Alternative**: professional
163 | **Category**: Gendered term
164 | **Context**: Avoid since it is skewed to a particular gender.
165 | **Link**: https://learn.joinhandshake.com/employers/70-inclusive-language-principles-that-will-make-you-a-more-successful-recruiter/
166 | 167 | - housekeeping
168 | **Alternative**: maintenance, cleanup, preparation
169 | **Category**: Gendered term
170 | **Context**: Avoid since it is skewed to a particular gender. Consider using "maintenance" instead. When "housekeeping" is used in reference to office work, this language can feel gendered. Use of inclusive terms allow space for everyone’s identities.
171 | **Link**: https://buffer.com/resources/inclusive-language-tech/
172 | 173 | - opposite sex
174 | **Alternative**: different sex
175 | **Category**: Gendered term
176 | **Context**: Avoid binary gender terms, since gender can be placed on a spectrum. By avoiding binaries, we include all identities.
177 | **Link**: https://content-guide.18f.gov/our-style/inclusive-language/
178 | 179 | - grandfathered in, grandfathered
180 | **Alternative**:
181 | **Category**: Ageism
182 | **Context**: Consider using a neutral alternative such as "exempt." Historical context of "grandfathered" alludes to disenfranchisement in the United States of black Americans. It was used to allow white men to vote as long as their lineal ancestor (i.e., grandfather) had been a registered voter before 1867.
183 | **Link**: https://history.howstuffworks.com/american-civil-war/grandfathered-in.htm
184 | 185 | - old
186 | **Alternative**: --
187 | **Category**: Ageism
188 | **Context**: Avoid using age in a derogatory context. Negative connotation can be associated with terms related to old age.
189 | **Link**: https://consciousstyleguide.com/age/
190 | https://content-guide.18f.gov/our-style/inclusive-language/
191 | 192 | - young
193 | **Alternative**: --
194 | **Category**: Ageism
195 | **Context**: Avoid using age in a derogatory context. Negative connotation can be associated with terms related to young age.
196 | **Link**: https://consciousstyleguide.com/age/
197 | https://content-guide.18f.gov/our-style/inclusive-language/
198 | 199 | - normal
200 | **Alternative**: typical, expected, healthy
201 | **Category**: Accessibility
202 | **Context**: Avoid using term "normal" since referring to persons without disabilities as normal, healthy, accessible or other such term may be offensive to people with disabilities as it insinuates that they are not normal or otherwise healthy. In the past, terms used to describe people with disabilities were often inaccurate, and sometimes even belittling and derogatory.
203 | **Link**: http://www.mauracullen.com/wp-content/uploads/2011/09/How-Being-Polite-Can-Be-Insensitive-to-People-with-Disabilities.pdf
204 | 205 | - midget
206 | **Alternative**: little person, short stature, person with dwarfism
207 | **Category**: Accessibility
208 | **Context**: The term “midget” is considered outdated and derogatory when referring to those with shorter heights or the medical condition, dwarfism. The Little People of America organization recommends using the descriptors "short stature," "little person" or "person with dwarfism."
209 | **Link**: https://www.diversitystyleguide.com/glossary/dwarf-little-person-midget-short-stature/
210 | 211 | - crazy
212 | **Alternative**: unexpected, unpredictable, surprising
213 | **Category**: Accessibility
214 | **Context**: Avoid using as these terms are commonly used informally to denote mental instability or mental illness but can be considered offensive. The repeated use perpetuates stigma and belittles mental condition that can make it more difficult for people to seek treatment.
215 | **Link**: https://www.pennmedicine.org/news/news-blog/2018/september/that-crazy-why-you-might-want-to-rethink-that-word-in-your-vocabulary
216 | https://content-guide.18f.gov/our-style/inclusive-language/
217 | 218 | - insane
219 | **Alternative**: unexpected, unpredictable, surprising
220 | **Category**: Accessibility
221 | **Context**: Avoid using as these terms are commonly used informally to denote mental instability or mental illness but can be considered offensive. The repeated use perpetuates stigma and belittles mental condition that can make it more difficult for people to seek treatment.
222 | **Link**: https://www.pennmedicine.org/news/news-blog/2018/september/that-crazy-why-you-might-want-to-rethink-that-word-in-your-vocabulary
223 | https://content-guide.18f.gov/our-style/inclusive-language/
224 | 225 | - freak(y)
226 | **Alternative**: unexpected, unpredictable, surprising
227 | **Category**: Accessibility
228 | **Context**: Avoid using as these terms are commonly used informally to denote mental instability or mental illness but can be considered offensive. The repeated use perpetuates stigma and belittles mental condition that can make it more difficult for people to seek treatment.
229 | **Link**: https://www.pennmedicine.org/news/news-blog/2018/september/that-crazy-why-you-might-want-to-rethink-that-word-in-your-vocabulary
230 | https://content-guide.18f.gov/our-style/inclusive-language/
231 | 232 | - tone deaf
233 | **Alternative**: oblivious
234 | **Category**: Accessibility
235 | **Context**: Be aware that "tone deaf" refers to having or showing an obtuse insensitivity or lack of perception particularly in matters of public sentiment, opinion, or taste. It may be offensive for those that have hearing loss or impairment.
236 | **Link**: https://www.thereadyset.co/blog/disability-justice-in-the-workplace
237 | 238 | - blind spot
239 | **Alternative**: dead spot, unseen area
240 | **Category**: Accessibility
241 | **Context**: Be aware that "blind spot" has a negative connotation with lack of wisdom or inability to exercise judgment. It may cause offense to those that have loss of sight or impairment.
242 | **Link**: https://content-guide.18f.gov/our-style/inclusive-language/
243 | 244 | - OCD
245 | **Alternative**: organized, detail-oriented
246 | **Category**: Accessibility
247 | **Context**: Unless if used in the correct context, be aware that the incorrect use of the term “OCD” trivializes the mental illness. It can make it more difficult for people to seek treatment or can belittle their condition.
248 | **Link**: https://www.huffpost.com/entry/mental-illness-comics_n_58d17809e4b0ec9d29e00bc9
249 | 250 | - depressed/depressing
251 | **Alternative**: sad/saddening, upset/upsetting
252 | **Category**: Accessibility
253 | **Context**: Unless if used in the correct context, be aware that the incorrect use of term “depressed” trivializes the mental illness. It can make it more difficult for people to seek treatment or can belittle their condition.
254 | **Link**: https://www.wbur.org/cognoscenti/2018/05/29/mental-health-awareness-month-jane-roper
255 | 256 | - handicap/handicapped
257 | **Alternative**: person with a disability
258 | **Category**: Accessibility
259 | **Context**: By using a more accessible phrase like "person with disability" you avoid defining the person by their disabilities. Discrimination or prejudice against individuals with disabilities reflects the dominant attitudes in society that assume that some characteristics are better than others and excludes people with disabilities.
260 | **Link**: https://ncdj.org/style-guide/
261 | 262 | - disabled
263 | **Alternative**: person with a disability
264 | **Category**: Accessibility
265 | **Context**: Using the term "disabled" describes the person by their disabilities. By using a more accessible phrase like "person with disability" you avoid defining the person by their disabilities. Discrimination or prejudice against individuals with disabilities reflects the dominant attitudes in society that assume that some characteristics are better than others and excludes people with disabilities.
266 | **Link**: https://ncdj.org/style-guide/
267 | 268 | - cripple/crippled
269 | **Alternative**: person with a disability
270 | **Category**: Accessibility
271 | **Context**: By using a more accessible phrase like "person with disability" you avoid defining the person by their disabilities. Discrimination or prejudice against individuals with disabilities reflects the dominant attitudes in society that assume that some characteristics are better than others and excludes people with disabilities.
272 | **Link**: https://ncdj.org/style-guide/
273 | 274 | - sanity check
275 | **Alternative**: quick check, confidence check, coherence check
276 | **Category**: Accessibility
277 | **Context**: Avoid using terms like "sane" and "sanity" as it perpetuates the societal stigma of the preferred condition of sanity, while excluding those who suffer mental instability and mental illness. Furthermore, discrimination or prejudice against individuals with disabilities reflects the dominant attitudes in society that assume that some characteristics are better than others and excludes people with disabilities.
278 | **Link**: https://ncdj.org/style-guide/
279 | 280 | - sane
281 | **Alternative**: correct, adequate, sufficient, valid, sensible, coherent
282 | **Category**: Accessibility
283 | **Context**: Avoid using terms like "sane" and "sanity" as it perpetuates the societal stigma of the preferred condition of sanity, while excluding those who suffer mental instability and mental illness. Furthermore, discrimination or prejudice against individuals with disabilities reflects the dominant attitudes in society that assume that some characteristics are better than others and excludes people with disabilities.
284 | **Link**: https://ncdj.org/style-guide/
285 | 286 | - retard
287 | **Alternative**: person with disabilities, mentally limited
288 | **Category**: Accessibility
289 | **Context**: The terms “mentally retarded,” “retard” and “mental retardation” were once common terms that are now considered outdated and offensive. In 2010, President Barack Obama signed a measure known as “Rosa’s Law” that replaced the term “mental retardation” with intellectual disability in many areas of government, including federal law.
290 | **Link**: https://ncdj.org/style-guide/
291 | http://www.mauracullen.com/wp-content/uploads/2011/09/How-Being-Polite-Can-Be-Insensitive-to-People-with-Disabilities.pdf
292 | 293 | - dummy value
294 | **Alternative**: placeholder value, sample value, design value
295 | **Category**: Accessibility
296 | **Context**: Be aware that for people with mental illness commonly used terms like "dummy" can perpetuate negative stigma of otherness and inferiority. Try using a neutral or descriptive term instead.
297 | **Link**: https://developers.google.com/style/word-list
298 | --------------------------------------------------------------------------------