├── .gitignore ├── BitFields.sln ├── LICENSE ├── README.md ├── docs ├── bitfieldgenerator.png └── bitn.png ├── experimental ├── ConsoleApp1 │ ├── BitFields │ │ ├── DoubleView.cs │ │ └── Program.cs │ ├── ConsoleApp1.csproj │ ├── GenericBits │ │ ├── Program.cs │ │ ├── Sample1.cs │ │ └── Sample2.cs │ ├── Program.cs │ └── TypeClassBits │ │ ├── DoubleView.cs │ │ └── Program.cs ├── GenericBits │ ├── Bits.cs │ └── GenericBits.csproj └── TypeClassBits │ ├── Bits_M_N.cs │ ├── IConstant.cs │ ├── ILogicalOperator.cs │ ├── IntConstants.cs │ ├── LogicalOperators.cs │ └── TypeClassBits.csproj ├── src ├── .gitignore ├── BitFields.nuspec ├── BitFields │ ├── Bit.cs │ ├── Bit.tt │ └── BitFields.csproj ├── BitFieldsAnalyzer │ ├── BitFieldsAnalyzer.Test │ │ ├── BitFieldGeneratorTest.cs │ │ ├── BitFieldsAnalyzer.Test.csproj │ │ ├── Helpers │ │ │ ├── CodeFixVerifier.Helper.cs │ │ │ ├── DiagnosticResult.cs │ │ │ └── DiagnosticVerifier.Helper.cs │ │ ├── UnitTests.cs │ │ └── Verifiers │ │ │ ├── CodeFixVerifier.cs │ │ │ └── DiagnosticVerifier.cs │ ├── BitFieldsAnalyzer.Vsix │ │ ├── BitFieldsAnalyzer.Vsix.csproj │ │ └── source.extension.vsixmanifest │ └── BitFieldsAnalyzer │ │ ├── BitField.cs │ │ ├── BitFieldGeneratorAnalyzer.cs │ │ ├── BitFieldGeneratorCodeFixProvider.cs │ │ ├── BitFieldsAnalyzer.csproj │ │ ├── BitNAnalyzer.cs │ │ ├── Diagnostic.nuspec │ │ ├── ReadMe.txt │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── SyntaxExtensions.cs │ │ └── Util.cs ├── pack.bat └── restore.ps1 └── tests └── TargetFrameworks ├── ClassLibraryNewCsprojNet35 ├── Class1.cs └── ClassLibraryNewCsprojNet35.csproj ├── ClassLibraryNewCsprojNet462 ├── Class1.cs ├── ClassLibraryNewCsprojNet462.csproj └── Flags.BitFields.cs ├── ClassLibraryNewCsprojStd10 ├── Class1.cs ├── ClassLibraryNewCsprojStd10.csproj └── Flags.BitFields.cs ├── ClassLibraryNewCsprojStd14 ├── Class1.cs ├── ClassLibraryNewCsprojStd14.csproj └── Flags.BitFields.cs ├── ClassLibraryNewCsprojStd16 ├── Class1.cs ├── ClassLibraryNewCsprojStd16.csproj └── Flags.BitFields.cs ├── ClassLibraryOldCsprojNet35 ├── Class1.cs ├── ClassLibraryOldCsprojNet35.csproj └── Properties │ └── AssemblyInfo.cs ├── ClassLibraryOldCsprojNet462 ├── Class1.cs ├── ClassLibraryOldCsprojNet462.csproj ├── Flags.BitFields.cs └── Properties │ └── AssemblyInfo.cs ├── ClassLibraryPcl ├── Class1.cs ├── ClassLibraryPcl.csproj └── Properties │ └── AssemblyInfo.cs ├── ConsoleAppCore ├── ConsoleAppCore.csproj ├── Flags.BitFields.cs └── Program.cs ├── ConsoleAppNet35 ├── App.config ├── ConsoleAppNet35.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── ConsoleAppNet4 ├── App.config ├── ConsoleAppNet4.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── ConsoleAppNet45 ├── App.config ├── ConsoleAppNet45.csproj ├── Flags.BitFields.cs ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── ConsoleAppNet462 ├── App.config ├── ConsoleAppNet462.csproj ├── Flags.BitFields.cs ├── Program.cs └── Properties │ └── AssemblyInfo.cs └── TargetFrameworks.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /BitFields.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{36A89821-EC52-4181-B9AE-29ECE656397E}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "experimental", "experimental", "{BB961ACF-FF36-4F16-8C0F-8BC5E6BDDF84}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BitFields", "src\BitFields\BitFields.csproj", "{C19FE8B5-D129-45DD-A695-BCEC62BAFF49}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp1", "experimental\ConsoleApp1\ConsoleApp1.csproj", "{363F4419-1E1D-4760-80FA-26FE7F332C6C}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GenericBits", "experimental\GenericBits\GenericBits.csproj", "{1991D425-2FF4-4D0C-8453-BC9B89005F99}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TypeClassBits", "experimental\TypeClassBits\TypeClassBits.csproj", "{50A4BC0C-EF7B-420D-8AE0-CDE0851F0424}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BitFieldsAnalyzer", "src\BitFieldsAnalyzer\BitFieldsAnalyzer\BitFieldsAnalyzer.csproj", "{EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitFieldsAnalyzer.Test", "src\BitFieldsAnalyzer\BitFieldsAnalyzer.Test\BitFieldsAnalyzer.Test.csproj", "{BB2F0E80-A4AF-47C5-84DC-D10B6180403F}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BitFieldsAnalyzer.Vsix", "src\BitFieldsAnalyzer\BitFieldsAnalyzer.Vsix\BitFieldsAnalyzer.Vsix.csproj", "{5106E44E-D56B-4654-8D6A-9F6B782DB09D}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {C19FE8B5-D129-45DD-A695-BCEC62BAFF49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {C19FE8B5-D129-45DD-A695-BCEC62BAFF49}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {C19FE8B5-D129-45DD-A695-BCEC62BAFF49}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {C19FE8B5-D129-45DD-A695-BCEC62BAFF49}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {363F4419-1E1D-4760-80FA-26FE7F332C6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {363F4419-1E1D-4760-80FA-26FE7F332C6C}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {363F4419-1E1D-4760-80FA-26FE7F332C6C}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {363F4419-1E1D-4760-80FA-26FE7F332C6C}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {1991D425-2FF4-4D0C-8453-BC9B89005F99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {1991D425-2FF4-4D0C-8453-BC9B89005F99}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {1991D425-2FF4-4D0C-8453-BC9B89005F99}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {1991D425-2FF4-4D0C-8453-BC9B89005F99}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {50A4BC0C-EF7B-420D-8AE0-CDE0851F0424}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {50A4BC0C-EF7B-420D-8AE0-CDE0851F0424}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {50A4BC0C-EF7B-420D-8AE0-CDE0851F0424}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {50A4BC0C-EF7B-420D-8AE0-CDE0851F0424}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {BB2F0E80-A4AF-47C5-84DC-D10B6180403F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {BB2F0E80-A4AF-47C5-84DC-D10B6180403F}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {BB2F0E80-A4AF-47C5-84DC-D10B6180403F}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {BB2F0E80-A4AF-47C5-84DC-D10B6180403F}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D}.Release|Any CPU.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(NestedProjects) = preSolution 63 | {C19FE8B5-D129-45DD-A695-BCEC62BAFF49} = {36A89821-EC52-4181-B9AE-29ECE656397E} 64 | {363F4419-1E1D-4760-80FA-26FE7F332C6C} = {BB961ACF-FF36-4F16-8C0F-8BC5E6BDDF84} 65 | {1991D425-2FF4-4D0C-8453-BC9B89005F99} = {BB961ACF-FF36-4F16-8C0F-8BC5E6BDDF84} 66 | {50A4BC0C-EF7B-420D-8AE0-CDE0851F0424} = {BB961ACF-FF36-4F16-8C0F-8BC5E6BDDF84} 67 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1} = {36A89821-EC52-4181-B9AE-29ECE656397E} 68 | {BB2F0E80-A4AF-47C5-84DC-D10B6180403F} = {36A89821-EC52-4181-B9AE-29ECE656397E} 69 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D} = {36A89821-EC52-4181-B9AE-29ECE656397E} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nobuyuki Iwanaga 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 | # BitFields 2 | 3 | NuGet Package: https://www.nuget.org/packages/BitFields/ 4 | 5 | The analyzer in this package currently does not support `packages.config` format. 6 | 7 | ## N-bit Ingeters 8 | 9 | ![N-bit integers](docs/bitn.png) 10 | 11 | ## Bit-field Generator 12 | 13 | Type definition: 14 | 15 | ```cs 16 | struct Rgb555 17 | { 18 | enum BitFields 19 | { 20 | B = 5, 21 | G = 5, 22 | R = 5, 23 | } 24 | } 25 | ``` 26 | 27 | Quick Action: 28 | 29 | ![Quick Action to generate bit-fields](docs/bitfieldgenerator.png) 30 | 31 | Generated code: 32 | 33 | ```cs 34 | using BitFields; 35 | 36 | partial struct Rgb555 37 | { 38 | public ushort Value; 39 | 40 | private const int BShift = 0; 41 | private const ushort BMask = unchecked((ushort)((1U << 5) - (1U << 0))); 42 | public Bit5 B 43 | { 44 | get => (Bit5)((Value & BMask) >> BShift); 45 | set => Value = unchecked((ushort)((Value & ~BMask) | ((((ushort)value) << BShift) & BMask))); 46 | } 47 | private const int GShift = 5; 48 | private const ushort GMask = unchecked((ushort)((1U << 10) - (1U << 5))); 49 | public Bit5 G 50 | { 51 | get => (Bit5)((Value & GMask) >> GShift); 52 | set => Value = unchecked((ushort)((Value & ~GMask) | ((((ushort)value) << GShift) & GMask))); 53 | } 54 | private const int RShift = 10; 55 | private const ushort RMask = unchecked((ushort)((1U << 15) - (1U << 10))); 56 | public Bit5 R 57 | { 58 | get => (Bit5)((Value & RMask) >> RShift); 59 | set => Value = unchecked((ushort)((Value & ~RMask) | ((((ushort)value) << RShift) & RMask))); 60 | } 61 | } 62 | ``` 63 | -------------------------------------------------------------------------------- /docs/bitfieldgenerator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufcpp/BitFields/8f947dacc5a190f049cbedc8c58ba8ab220cd205/docs/bitfieldgenerator.png -------------------------------------------------------------------------------- /docs/bitn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ufcpp/BitFields/8f947dacc5a190f049cbedc8c58ba8ab220cd205/docs/bitn.png -------------------------------------------------------------------------------- /experimental/ConsoleApp1/BitFields/DoubleView.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace ConsoleApp1.BitFields 5 | { 6 | struct DoubleView 7 | { 8 | public ulong Value; 9 | 10 | public double AsDouble() => Unsafe.As(ref Value); 11 | 12 | private const int FractionShift = 0; 13 | private const ulong FractionMask = unchecked((1UL << 52) - (1UL << 0)); 14 | public Bit52 Fraction 15 | { 16 | get => (Bit52)((Value & FractionMask) >> FractionShift); 17 | set => Value = (Value & ~FractionMask) | ((((ulong)value) << FractionShift) & FractionMask); 18 | } 19 | 20 | private const int ExponentShift = 52; 21 | private const ulong ExponentMask = unchecked((1UL << 63) - (1UL << 52)); 22 | public Bit11 Exponent 23 | { 24 | get => (Bit11)((Value & ExponentMask) >> ExponentShift); 25 | set => Value = (Value & ~ExponentMask) | ((((ulong)value) << ExponentShift) & ExponentMask); 26 | } 27 | 28 | private const int SignShift = 63; 29 | private const ulong SignMask = unchecked((1UL << 64) - (1UL << 63)); 30 | public Bit1 Sign 31 | { 32 | get => (Bit1)((Value & SignMask) >> SignShift); 33 | set => Value = (Value & ~SignMask) | ((((ulong)value) << SignShift) & SignMask); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/BitFields/Program.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | using System; 3 | 4 | namespace ConsoleApp1.BitFields 5 | { 6 | class Program 7 | { 8 | public static void Run() 9 | { 10 | var v = new DoubleView(); 11 | 12 | v.Sign = 1; // - 13 | v.Exponent = 3 + 1023; // 2^3 14 | v.Fraction = 0xE_0000_0000_0000; // 1.111b 15 | 16 | Console.WriteLine(v.AsDouble()); // -15 17 | 18 | Bit3 x = 1; 19 | x = 4; 20 | x = 10; 21 | } 22 | 23 | Bit2 x = 1; 24 | Bit2 y = 4; 25 | 26 | Bit1 X { get; } = 1; 27 | Bit1 Y { get; } = 2; 28 | 29 | void A() 30 | { 31 | A(1); 32 | A(2); 33 | } 34 | void A(Bit1 x) { } 35 | Bit1 F() => 2; 36 | Bit1 Z => 2; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/ConsoleApp1.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp1.1 6 | 7 | 8 | 9 | True 10 | 11 | 12 | 13 | True 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/GenericBits/Program.cs: -------------------------------------------------------------------------------- 1 | using GenericBits; 2 | using System; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace ConsoleApp1.GenericBits 6 | { 7 | class Program 8 | { 9 | public static void Run() 10 | { 11 | Write((byte)0x12); 12 | Write((short)0x1234); 13 | Write(0x1234_5678); 14 | Write(0x12345678abcdef0L); 15 | Write(new Sample1(0x12, 0x34, 0x5678, 0x9abcdef0)); 16 | Write(new Sample2(0x1234, 0x5678_9abc, 0xde, 0x1234_5678_9abc_def0L)); 17 | } 18 | 19 | static void Write(T initialValue) 20 | where T : struct 21 | { 22 | Console.WriteLine($"---- write bits for {typeof(T).Name} (size = {Unsafe.SizeOf()}) ----"); 23 | 24 | var x = initialValue; 25 | var bits = new Bits(ref x); 26 | Console.WriteLine($"bits: {bits.Count}"); 27 | Console.WriteLine(x); 28 | WriteBits(bits); 29 | 30 | for (int i = 0; i < bits.Count; i++) bits[i] = (i % 2) == 1; 31 | Console.WriteLine(x); 32 | WriteBits(bits); 33 | 34 | for (int i = 0; i < bits.Count; i++) bits[i] = (i % 3) == 1; 35 | Console.WriteLine(x); 36 | WriteBits(bits); 37 | } 38 | 39 | static void WriteBits(Bits bits) 40 | where T : struct 41 | { 42 | for (int i = 0; i < bits.Count; i++) 43 | { 44 | if ((i % 4 == 0 && i != 0)) Console.Write('_'); 45 | Console.Write(bits[i] ? '1' : '0'); 46 | } 47 | Console.WriteLine(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/GenericBits/Sample1.cs: -------------------------------------------------------------------------------- 1 | namespace ConsoleApp1.GenericBits 2 | { 3 | struct Sample1 4 | { 5 | public byte A; 6 | public byte B; 7 | public ushort C; 8 | public uint D; 9 | public Sample1(byte a, byte b, ushort c, uint d) => (A, B, C, D) = (a, b, c, d); 10 | public override string ToString() => (A, B, C, D).ToString(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/GenericBits/Sample2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace ConsoleApp1.GenericBits 6 | { 7 | struct Sample2 8 | { 9 | public short A; 10 | public int B; 11 | public byte C; 12 | public long D; 13 | public Sample2(short a, int b, byte c, long d) => (A, B, C, D) = (a, b, c, d); 14 | public override string ToString() => (A, B, C, D).ToString(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ConsoleApp1 4 | { 5 | class Program 6 | { 7 | static void Main(string[] args) 8 | { 9 | BitFields.Program.Run(); 10 | TypeClassBits.Program.Run(); 11 | GenericBits.Program.Run(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /experimental/ConsoleApp1/TypeClassBits/DoubleView.cs: -------------------------------------------------------------------------------- 1 | using TypeClassBits; 2 | using static TypeClassBits.IntConstants; 3 | using System.Runtime.CompilerServices; 4 | 5 | namespace ConsoleApp1.TypeClassBits 6 | { 7 | struct DoubleView 8 | { 9 | public ulong Value; 10 | 11 | public double AsDouble() => Unsafe.As(ref Value); 12 | 13 | public Bits Fraction => new Bits(ref Value); 14 | public Bits Exponent => new Bits(ref Value); 15 | public Bits Sign => new Bits(ref Value); 16 | 17 | public void Deconstruct( 18 | out Bits fraction, 19 | out Bits exponent, 20 | out Bits sign) 21 | => (fraction, exponent, sign) = (Fraction, Exponent, Sign); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /experimental/ConsoleApp1/TypeClassBits/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ConsoleApp1.TypeClassBits 4 | { 5 | class Program 6 | { 7 | public static void Run() 8 | { 9 | var v = new DoubleView(); 10 | 11 | var (f, e, s) = v; 12 | s.Value = 1; // - 13 | e.Value = 3 + 1023; // 2^3 14 | f.Value = 0xE_0000_0000_0000; // 1.111b 15 | 16 | Console.WriteLine(v.AsDouble()); // -15 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /experimental/GenericBits/Bits.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace GenericBits 7 | { 8 | public unsafe struct Bits : IEnumerable, IReadOnlyList 9 | where T : struct 10 | { 11 | private static readonly int NumBits = Unsafe.SizeOf() * 8; 12 | 13 | private byte* _ptr; 14 | public Bits(ref T x) => _ptr = (byte*)Unsafe.AsPointer(ref x); 15 | 16 | const int Shift = 3; 17 | const int Mask = 0b111; 18 | 19 | public bool this[int index] 20 | { 21 | get 22 | { 23 | if (index >= NumBits) throw new IndexOutOfRangeException(); 24 | return (_ptr[index >> Shift] & (1 << (index & Mask))) != 0; 25 | } 26 | set 27 | { 28 | if (index >= NumBits) throw new IndexOutOfRangeException(); 29 | if (value) _ptr[index >> Shift] |= (byte)(1UL << (index & Mask)); 30 | else _ptr[index >> Shift] &= (byte)~(1 << (index & Mask)); 31 | } 32 | } 33 | 34 | public int Count => NumBits; 35 | 36 | public Enumerator GetEnumerator() => new Enumerator(this); 37 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 38 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 39 | 40 | public struct Enumerator : IEnumerator 41 | { 42 | private int _i; 43 | private Bits _bits; 44 | public Enumerator(Bits bits) => (_bits, _i) = (bits, -1); 45 | 46 | public bool Current => _bits[_i]; 47 | object IEnumerator.Current => Current; 48 | public void Dispose() { } 49 | public bool MoveNext() => ++_i < _bits.Count; 50 | public void Reset() => _i = -1; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /experimental/GenericBits/GenericBits.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.4 5 | 6 | 7 | 8 | True 9 | 10 | 11 | 12 | True 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/Bits_M_N.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Runtime.CompilerServices; 5 | 6 | namespace TypeClassBits 7 | { 8 | public unsafe struct Bits : IEnumerable, IReadOnlyList 9 | where T : struct 10 | where TOp : ILogicalOperator 11 | where LowBit : IConstant 12 | where HighBit : IConstant 13 | { 14 | private static int NumBits => default(HighBit).Value - default(LowBit).Value; 15 | 16 | // I want to use ByReferenct if possible 17 | // https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/ByReference.cs 18 | private void* _ptr; 19 | public Bits(void* ptr) => _ptr = ptr; 20 | public Bits(ref T x) : this(Unsafe.AsPointer(ref x)) { } 21 | 22 | private ref T Reference => ref Unsafe.AsRef(_ptr); 23 | 24 | private static readonly T ValueMask = default(TOp).As((1UL << default(HighBit).Value) - (1UL << default(LowBit).Value)); 25 | private static readonly T NotValueMask = default(TOp).Not(ValueMask); 26 | 27 | public T Value 28 | { 29 | get 30 | { 31 | var r = Reference; 32 | default(TOp).And(ref r, ValueMask); 33 | default(TOp).RightShift(ref r, default(LowBit).Value); 34 | return r; 35 | } 36 | set 37 | { 38 | ref var r = ref Reference; 39 | default(TOp).And(ref r, NotValueMask); 40 | default(TOp).LeftShift(ref value, default(LowBit).Value); 41 | default(TOp).And(ref value, ValueMask); 42 | default(TOp).Or(ref r, value); 43 | } 44 | } 45 | 46 | const int BitShift = 3; 47 | const int BitMask = 0b111; 48 | 49 | private bool GetNthBit(int n) 50 | { 51 | CheckRange(n); 52 | var r = Reference; 53 | var mask = default(TOp).One; 54 | default(TOp).LeftShift(ref mask, n); 55 | default(TOp).And(ref r, mask); 56 | return !default(TOp).IsZero(r); 57 | } 58 | 59 | private void SetNthBit(int n, bool value) 60 | { 61 | CheckRange(n); 62 | 63 | ref var r = ref Reference; 64 | 65 | var mask = default(TOp).One; 66 | default(TOp).LeftShift(ref mask, n); 67 | 68 | if (value) 69 | { 70 | default(TOp).Or(ref r, mask); 71 | } 72 | else 73 | { 74 | mask = default(TOp).Not(mask); 75 | default(TOp).And(ref r, mask); 76 | } 77 | } 78 | 79 | private static void CheckRange(int i) 80 | { 81 | if (i < default(LowBit).Value) throw new IndexOutOfRangeException(); 82 | else if (i >= default(HighBit).Value) throw new IndexOutOfRangeException(); 83 | } 84 | 85 | public bool this[int index] 86 | { 87 | get => GetNthBit(index + default(LowBit).Value); 88 | set => SetNthBit(index + default(LowBit).Value, value); 89 | } 90 | 91 | public int Count => NumBits; 92 | 93 | public Enumerator GetEnumerator() => new Enumerator(this); 94 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 95 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 96 | 97 | public struct Enumerator : IEnumerator 98 | { 99 | private int _i; 100 | private Bits _bits; 101 | public Enumerator(Bits bits) => (_bits, _i) = (bits, default(LowBit).Value - 1); 102 | 103 | public bool Current => _bits.GetNthBit(_i); 104 | object IEnumerator.Current => Current; 105 | public void Dispose() { } 106 | public bool MoveNext() => ++_i < default(HighBit).Value; 107 | public void Reset() => _i = -1; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/IConstant.cs: -------------------------------------------------------------------------------- 1 | namespace TypeClassBits 2 | { 3 | public interface IConstant 4 | { 5 | T Value { get; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/ILogicalOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace TypeClassBits 6 | { 7 | public interface ILogicalOperator 8 | { 9 | T One { get; } 10 | T As(ulong value); 11 | T Not(T value); 12 | void And(ref T x, T y); 13 | void Or(ref T x, T y); 14 | void LeftShift(ref T x, int i); 15 | void RightShift(ref T x, int i); 16 | bool IsZero(T x); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/IntConstants.cs: -------------------------------------------------------------------------------- 1 | namespace TypeClassBits 2 | { 3 | public static class IntConstants 4 | { 5 | public struct _0 : IConstant { public int Value => 0; } 6 | public struct _1 : IConstant { public int Value => 1; } 7 | public struct _2 : IConstant { public int Value => 2; } 8 | public struct _3 : IConstant { public int Value => 3; } 9 | public struct _4 : IConstant { public int Value => 4; } 10 | public struct _5 : IConstant { public int Value => 5; } 11 | public struct _6 : IConstant { public int Value => 6; } 12 | public struct _7 : IConstant { public int Value => 7; } 13 | public struct _8 : IConstant { public int Value => 8; } 14 | public struct _9 : IConstant { public int Value => 9; } 15 | public struct _10 : IConstant { public int Value => 10; } 16 | public struct _11 : IConstant { public int Value => 11; } 17 | public struct _12 : IConstant { public int Value => 12; } 18 | public struct _13 : IConstant { public int Value => 13; } 19 | public struct _14 : IConstant { public int Value => 14; } 20 | public struct _15 : IConstant { public int Value => 15; } 21 | public struct _16 : IConstant { public int Value => 16; } 22 | public struct _17 : IConstant { public int Value => 17; } 23 | public struct _18 : IConstant { public int Value => 18; } 24 | public struct _19 : IConstant { public int Value => 19; } 25 | public struct _20 : IConstant { public int Value => 20; } 26 | public struct _21 : IConstant { public int Value => 21; } 27 | public struct _22 : IConstant { public int Value => 22; } 28 | public struct _23 : IConstant { public int Value => 23; } 29 | public struct _24 : IConstant { public int Value => 24; } 30 | public struct _25 : IConstant { public int Value => 25; } 31 | public struct _26 : IConstant { public int Value => 26; } 32 | public struct _27 : IConstant { public int Value => 27; } 33 | public struct _28 : IConstant { public int Value => 28; } 34 | public struct _29 : IConstant { public int Value => 29; } 35 | public struct _30 : IConstant { public int Value => 30; } 36 | public struct _31 : IConstant { public int Value => 31; } 37 | public struct _32 : IConstant { public int Value => 32; } 38 | public struct _33 : IConstant { public int Value => 33; } 39 | public struct _34 : IConstant { public int Value => 34; } 40 | public struct _35 : IConstant { public int Value => 35; } 41 | public struct _36 : IConstant { public int Value => 36; } 42 | public struct _37 : IConstant { public int Value => 37; } 43 | public struct _38 : IConstant { public int Value => 38; } 44 | public struct _39 : IConstant { public int Value => 39; } 45 | public struct _40 : IConstant { public int Value => 40; } 46 | public struct _41 : IConstant { public int Value => 41; } 47 | public struct _42 : IConstant { public int Value => 42; } 48 | public struct _43 : IConstant { public int Value => 43; } 49 | public struct _44 : IConstant { public int Value => 44; } 50 | public struct _45 : IConstant { public int Value => 45; } 51 | public struct _46 : IConstant { public int Value => 46; } 52 | public struct _47 : IConstant { public int Value => 47; } 53 | public struct _48 : IConstant { public int Value => 48; } 54 | public struct _49 : IConstant { public int Value => 49; } 55 | public struct _50 : IConstant { public int Value => 50; } 56 | public struct _51 : IConstant { public int Value => 51; } 57 | public struct _52 : IConstant { public int Value => 52; } 58 | public struct _53 : IConstant { public int Value => 53; } 59 | public struct _54 : IConstant { public int Value => 54; } 60 | public struct _55 : IConstant { public int Value => 55; } 61 | public struct _56 : IConstant { public int Value => 56; } 62 | public struct _57 : IConstant { public int Value => 57; } 63 | public struct _58 : IConstant { public int Value => 58; } 64 | public struct _59 : IConstant { public int Value => 59; } 65 | public struct _60 : IConstant { public int Value => 60; } 66 | public struct _61 : IConstant { public int Value => 61; } 67 | public struct _62 : IConstant { public int Value => 62; } 68 | public struct _63 : IConstant { public int Value => 63; } 69 | public struct _64 : IConstant { public int Value => 64; } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/LogicalOperators.cs: -------------------------------------------------------------------------------- 1 | namespace TypeClassBits 2 | { 3 | public struct LogicalOperator8 : ILogicalOperator 4 | { 5 | public byte One => 1; 6 | public byte As(ulong value) => unchecked((byte)value); 7 | public byte Not(byte value) => unchecked((byte)~value); 8 | public void And(ref byte x, byte y) => x &= y; 9 | public void Or(ref byte x, byte y) => x |= y; 10 | public void LeftShift(ref byte x, int i) => x <<= i; 11 | public void RightShift(ref byte x, int i) => x >>= i; 12 | public bool IsZero(byte x) => x == 0; 13 | } 14 | 15 | public struct LogicalOperator16 : ILogicalOperator 16 | { 17 | public ushort One => 1; 18 | public ushort As(ulong value) => unchecked((ushort)value); 19 | public ushort Not(ushort value) => unchecked((ushort)~value); 20 | public void And(ref ushort x, ushort y) => x &= y; 21 | public void Or(ref ushort x, ushort y) => x |= y; 22 | public void LeftShift(ref ushort x, int i) => x <<= i; 23 | public void RightShift(ref ushort x, int i) => x >>= i; 24 | public bool IsZero(ushort x) => x == 0; 25 | } 26 | 27 | public struct LogicalOperator32 : ILogicalOperator 28 | { 29 | public uint One => 1; 30 | public uint As(ulong value) => unchecked((uint)value); 31 | public uint Not(uint value) => ~value; 32 | public void And(ref uint x, uint y) => x &= y; 33 | public void Or(ref uint x, uint y) => x |= y; 34 | public void LeftShift(ref uint x, int i) => x <<= i; 35 | public void RightShift(ref uint x, int i) => x >>= i; 36 | public bool IsZero(uint x) => x == 0; 37 | } 38 | 39 | public struct LogicalOperator64 : ILogicalOperator 40 | { 41 | public ulong One => 1; 42 | public ulong As(ulong value) => value; 43 | public ulong Not(ulong value) => ~value; 44 | public void And(ref ulong x, ulong y) => x &= y; 45 | public void Or(ref ulong x, ulong y) => x |= y; 46 | public void LeftShift(ref ulong x, int i) => x <<= i; 47 | public void RightShift(ref ulong x, int i) => x >>= i; 48 | public bool IsZero(ulong x) => x == 0; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /experimental/TypeClassBits/TypeClassBits.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.4 5 | 6 | 7 | 8 | True 9 | 10 | 11 | 12 | True 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | nuget.exe 2 | -------------------------------------------------------------------------------- /src/BitFields.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | BitFields 5 | 0.1.0 6 | BitFields 7 | Nobuyuki Iwanaga 8 | Nobuyuki Iwanaga 9 | https://github.com/ufcpp/BitFields/blob/master/LICENSE 10 | https://github.com/ufcpp/BitFields 11 | false 12 | Source Code Generator for BitFields structs. 13 | Initial release 14 | Nobuyuki Iwanaga 15 | BitFields, code generator 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/BitFields/Bit.tt: -------------------------------------------------------------------------------- 1 | <#@ template debug="false" hostspecific="false" language="C#" #> 2 | <#@ assembly name="System.Core" #> 3 | <#@ import namespace="System.Linq" #> 4 | <#@ import namespace="System.Text" #> 5 | <#@ import namespace="System.Collections.Generic" #> 6 | <#@ output extension=".cs" #> 7 | using System; 8 | 9 | namespace BitFields 10 | { 11 | <# 12 | var baseType = "byte"; 13 | 14 | for (var i = 1; i <= 64; i++) 15 | { 16 | if (i == 9) baseType = "ushort"; 17 | else if (i == 17) baseType = "uint"; 18 | else if (i == 33) baseType = "ulong"; 19 | 20 | #> 21 | public struct Bit<#= i #> : IEquatable> 22 | { 23 | public <#= baseType #> Value; 24 | public Bit<#= i #> (<#= baseType #> x) => Value = x; 25 | 26 | public bool Equals(Bit<#= i #> other) => Value == other.Value; 27 | public override bool Equals(object obj) => obj is Bit<#= i #> other && Equals(other); 28 | public override int GetHashCode() => Value.GetHashCode(); 29 | public static bool operator ==(Bit<#= i #> x, Bit<#= i #> y) => x.Value == y.Value; 30 | public static bool operator !=(Bit<#= i #> x, Bit<#= i #> y) => x.Value != y.Value; 31 | 32 | public static implicit operator Bit<#= i #>(<#= baseType #> x) => new Bit<#= i #>(x); 33 | public static implicit operator <#= baseType #>(Bit<#= i #> x) => x.Value; 34 | 35 | public override string ToString() => Value.ToString(); 36 | } 37 | <# 38 | } 39 | #> 40 | } 41 | -------------------------------------------------------------------------------- /src/BitFields/BitFields.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.0 5 | 6 | 7 | 8 | 9 | True 10 | True 11 | Bit.tt 12 | 13 | 14 | 15 | 16 | 17 | TextTemplatingFileGenerator 18 | Bit.cs 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | True 29 | True 30 | Bit.tt 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/BitFieldGeneratorTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeFixes; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using System; 5 | using TestHelper; 6 | using BitFieldsAnalyzer; 7 | using Xunit; 8 | using System.Collections.Generic; 9 | using Microsoft.CodeAnalysis.CodeActions; 10 | using System.Threading; 11 | 12 | namespace BitFieldsAnalyzer.Test 13 | { 14 | public class BitFieldGeneratorTest : CodeFixVerifier 15 | { 16 | [Fact] 17 | public void TestMethod0() 18 | { 19 | var test = @" 20 | struct DoubleView 21 | { 22 | enum BitFields 23 | { 24 | Fraction = 11, 25 | Exponent = 52, 26 | Sign = 1, 27 | } 28 | } 29 | 30 | struct Rgb555 31 | { 32 | enum BitFields 33 | { 34 | B = 5, 35 | G = 5, 36 | R = 5, 37 | } 38 | } 39 | "; 40 | VerifyCSharpFix(test, test); 41 | } 42 | 43 | protected override CodeFixProvider GetCSharpCodeFixProvider() 44 | { 45 | return new BitFieldGeneratorCodeFixProvider(); 46 | } 47 | 48 | protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() 49 | { 50 | return new BitFieldGeneratorAnalyzer(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/BitFieldsAnalyzer.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Library 4 | Properties 5 | BitFieldsAnalyzer.Test 6 | BitFieldsAnalyzer.Test 7 | netcoreapp1.0 8 | $(PackageTargetFallback);portable-net45+win8+wp8+wpa81 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1} 18 | BitFieldsAnalyzer 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/Helpers/CodeFixVerifier.Helper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeActions; 3 | using Microsoft.CodeAnalysis.Formatting; 4 | using Microsoft.CodeAnalysis.Simplification; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading; 8 | 9 | namespace TestHelper 10 | { 11 | /// 12 | /// Diagnostic Producer class with extra methods dealing with applying codefixes 13 | /// All methods are static 14 | /// 15 | public abstract partial class CodeFixVerifier : DiagnosticVerifier 16 | { 17 | /// 18 | /// Apply the inputted CodeAction to the inputted document. 19 | /// Meant to be used to apply codefixes. 20 | /// 21 | /// The Document to apply the fix on 22 | /// A CodeAction that will be applied to the Document. 23 | /// A Document with the changes from the CodeAction 24 | public static Document ApplyFix(Document document, CodeAction codeAction) 25 | { 26 | var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result; 27 | var solution = operations.OfType().Single().ChangedSolution; 28 | return solution.GetDocument(document.Id); 29 | } 30 | 31 | /// 32 | /// Compare two collections of Diagnostics,and return a list of any new diagnostics that appear only in the second collection. 33 | /// Note: Considers Diagnostics to be the same if they have the same Ids. In the case of multiple diagnostics with the same Id in a row, 34 | /// this method may not necessarily return the new one. 35 | /// 36 | /// The Diagnostics that existed in the code before the CodeFix was applied 37 | /// The Diagnostics that exist in the code after the CodeFix was applied 38 | /// A list of Diagnostics that only surfaced in the code after the CodeFix was applied 39 | private static IEnumerable GetNewDiagnostics(IEnumerable diagnostics, IEnumerable newDiagnostics) 40 | { 41 | var oldArray = diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); 42 | var newArray = newDiagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); 43 | 44 | int oldIndex = 0; 45 | int newIndex = 0; 46 | 47 | while (newIndex < newArray.Length) 48 | { 49 | if (oldIndex < oldArray.Length && oldArray[oldIndex].Id == newArray[newIndex].Id) 50 | { 51 | ++oldIndex; 52 | ++newIndex; 53 | } 54 | else 55 | { 56 | yield return newArray[newIndex++]; 57 | } 58 | } 59 | } 60 | 61 | /// 62 | /// Get the existing compiler diagnostics on the inputted document. 63 | /// 64 | /// The Document to run the compiler diagnostic analyzers on 65 | /// The compiler diagnostics that were found in the code 66 | private static IEnumerable GetCompilerDiagnostics(Document document) 67 | { 68 | return document.GetSemanticModelAsync().Result.GetDiagnostics(); 69 | } 70 | 71 | /// 72 | /// Given a document, turn it into a string based on the syntax root 73 | /// 74 | /// The Document to be converted to a string 75 | /// A string containing the syntax of the Document after formatting 76 | private static string GetStringFromDocument(Document document) 77 | { 78 | var simplifiedDoc = Simplifier.ReduceAsync(document, Simplifier.Annotation).Result; 79 | var root = simplifiedDoc.GetSyntaxRootAsync().Result; 80 | root = Formatter.Format(root, Formatter.Annotation, simplifiedDoc.Project.Solution.Workspace); 81 | return root.GetText().ToString(); 82 | } 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/Helpers/DiagnosticResult.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using System; 3 | 4 | namespace TestHelper 5 | { 6 | /// 7 | /// Location where the diagnostic appears, as determined by path, line number, and column number. 8 | /// 9 | public struct DiagnosticResultLocation 10 | { 11 | public DiagnosticResultLocation(string path, int line, int column) 12 | { 13 | if (line < -1) 14 | { 15 | throw new ArgumentOutOfRangeException(nameof(line), "line must be >= -1"); 16 | } 17 | 18 | if (column < -1) 19 | { 20 | throw new ArgumentOutOfRangeException(nameof(column), "column must be >= -1"); 21 | } 22 | 23 | this.Path = path; 24 | this.Line = line; 25 | this.Column = column; 26 | } 27 | 28 | public string Path { get; } 29 | public int Line { get; } 30 | public int Column { get; } 31 | } 32 | 33 | /// 34 | /// Struct that stores information about a Diagnostic appearing in a source 35 | /// 36 | public struct DiagnosticResult 37 | { 38 | private DiagnosticResultLocation[] locations; 39 | 40 | public DiagnosticResultLocation[] Locations 41 | { 42 | get 43 | { 44 | if (this.locations == null) 45 | { 46 | this.locations = new DiagnosticResultLocation[] { }; 47 | } 48 | return this.locations; 49 | } 50 | 51 | set 52 | { 53 | this.locations = value; 54 | } 55 | } 56 | 57 | public DiagnosticSeverity Severity { get; set; } 58 | 59 | public string Id { get; set; } 60 | 61 | public string Message { get; set; } 62 | 63 | public string Path 64 | { 65 | get 66 | { 67 | return this.Locations.Length > 0 ? this.Locations[0].Path : ""; 68 | } 69 | } 70 | 71 | public int Line 72 | { 73 | get 74 | { 75 | return this.Locations.Length > 0 ? this.Locations[0].Line : -1; 76 | } 77 | } 78 | 79 | public int Column 80 | { 81 | get 82 | { 83 | return this.Locations.Length > 0 ? this.Locations[0].Column : -1; 84 | } 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/Helpers/DiagnosticVerifier.Helper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using Microsoft.CodeAnalysis.Text; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Collections.Immutable; 8 | using System.Linq; 9 | using System.Reflection; 10 | 11 | namespace TestHelper 12 | { 13 | /// 14 | /// Class for turning strings into documents and getting the diagnostics on them 15 | /// All methods are static 16 | /// 17 | public abstract partial class DiagnosticVerifier 18 | { 19 | private static readonly MetadataReference CorlibReference = MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location); 20 | private static readonly MetadataReference SystemCoreReference = MetadataReference.CreateFromFile(typeof(Enumerable).GetTypeInfo().Assembly.Location); 21 | private static readonly MetadataReference CSharpSymbolsReference = MetadataReference.CreateFromFile(typeof(CSharpCompilation).GetTypeInfo().Assembly.Location); 22 | private static readonly MetadataReference CodeAnalysisReference = MetadataReference.CreateFromFile(typeof(Compilation).GetTypeInfo().Assembly.Location); 23 | 24 | internal static string DefaultFilePathPrefix = "Test"; 25 | internal static string CSharpDefaultFileExt = "cs"; 26 | internal static string VisualBasicDefaultExt = "vb"; 27 | internal static string TestProjectName = "TestProject"; 28 | 29 | #region Get Diagnostics 30 | 31 | /// 32 | /// Given classes in the form of strings, their language, and an IDiagnosticAnlayzer to apply to it, return the diagnostics found in the string after converting it to a document. 33 | /// 34 | /// Classes in the form of strings 35 | /// The language the source classes are in 36 | /// The analyzer to be run on the sources 37 | /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location 38 | protected static Diagnostic[] GetSortedDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer) 39 | { 40 | return GetSortedDiagnosticsFromDocuments(analyzer, GetDocuments(sources, language)); 41 | } 42 | 43 | /// 44 | /// Given an analyzer and a document to apply it to, run the analyzer and gather an array of diagnostics found in it. 45 | /// The returned diagnostics are then ordered by location in the source document. 46 | /// 47 | /// The analyzer to run on the documents 48 | /// The Documents that the analyzer will be run on 49 | /// An IEnumerable of Diagnostics that surfaced in the source code, sorted by Location 50 | protected static Diagnostic[] GetSortedDiagnosticsFromDocuments(DiagnosticAnalyzer analyzer, Document[] documents) 51 | { 52 | var projects = new HashSet(); 53 | foreach (var document in documents) 54 | { 55 | projects.Add(document.Project); 56 | } 57 | 58 | var diagnostics = new List(); 59 | foreach (var project in projects) 60 | { 61 | var compilationWithAnalyzers = project.GetCompilationAsync().Result.WithAnalyzers(ImmutableArray.Create(analyzer)); 62 | var diags = compilationWithAnalyzers.GetAnalyzerDiagnosticsAsync().Result; 63 | foreach (var diag in diags) 64 | { 65 | if (diag.Location == Location.None || diag.Location.IsInMetadata) 66 | { 67 | diagnostics.Add(diag); 68 | } 69 | else 70 | { 71 | for (int i = 0; i < documents.Length; i++) 72 | { 73 | var document = documents[i]; 74 | var tree = document.GetSyntaxTreeAsync().Result; 75 | if (tree == diag.Location.SourceTree) 76 | { 77 | diagnostics.Add(diag); 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | var results = SortDiagnostics(diagnostics); 85 | diagnostics.Clear(); 86 | return results; 87 | } 88 | 89 | /// 90 | /// Sort diagnostics by location in source document 91 | /// 92 | /// The list of Diagnostics to be sorted 93 | /// An IEnumerable containing the Diagnostics in order of Location 94 | private static Diagnostic[] SortDiagnostics(IEnumerable diagnostics) 95 | { 96 | return diagnostics.OrderBy(d => d.Location.SourceSpan.Start).ToArray(); 97 | } 98 | 99 | #endregion 100 | 101 | #region Set up compilation and documents 102 | /// 103 | /// Given an array of strings as sources and a language, turn them into a project and return the documents and spans of it. 104 | /// 105 | /// Classes in the form of strings 106 | /// The language the source code is in 107 | /// A Tuple containing the Documents produced from the sources and their TextSpans if relevant 108 | private static Document[] GetDocuments(string[] sources, string language) 109 | { 110 | if (language != LanguageNames.CSharp && language != LanguageNames.VisualBasic) 111 | { 112 | throw new ArgumentException("Unsupported Language"); 113 | } 114 | 115 | var project = CreateProject(sources, language); 116 | var documents = project.Documents.ToArray(); 117 | 118 | if (sources.Length != documents.Length) 119 | { 120 | throw new InvalidOperationException("Amount of sources did not match amount of Documents created"); 121 | } 122 | 123 | return documents; 124 | } 125 | 126 | /// 127 | /// Create a Document from a string through creating a project that contains it. 128 | /// 129 | /// Classes in the form of a string 130 | /// The language the source code is in 131 | /// A Document created from the source string 132 | protected static Document CreateDocument(string source, string language = LanguageNames.CSharp) 133 | { 134 | return CreateProject(new[] { source }, language).Documents.First(); 135 | } 136 | 137 | /// 138 | /// Create a project using the inputted strings as sources. 139 | /// 140 | /// Classes in the form of strings 141 | /// The language the source code is in 142 | /// A Project created out of the Documents created from the source strings 143 | private static Project CreateProject(string[] sources, string language = LanguageNames.CSharp) 144 | { 145 | string fileNamePrefix = DefaultFilePathPrefix; 146 | string fileExt = language == LanguageNames.CSharp ? CSharpDefaultFileExt : VisualBasicDefaultExt; 147 | 148 | var projectId = ProjectId.CreateNewId(debugName: TestProjectName); 149 | 150 | var solution = new AdhocWorkspace() 151 | .CurrentSolution 152 | .AddProject(projectId, TestProjectName, TestProjectName, language) 153 | .AddMetadataReference(projectId, CorlibReference) 154 | .AddMetadataReference(projectId, SystemCoreReference) 155 | .AddMetadataReference(projectId, CSharpSymbolsReference) 156 | .AddMetadataReference(projectId, CodeAnalysisReference); 157 | 158 | int count = 0; 159 | foreach (var source in sources) 160 | { 161 | var newFileName = fileNamePrefix + count + "." + fileExt; 162 | var documentId = DocumentId.CreateNewId(projectId, debugName: newFileName); 163 | solution = solution.AddDocument(documentId, newFileName, SourceText.From(source)); 164 | count++; 165 | } 166 | return solution.GetProject(projectId); 167 | } 168 | #endregion 169 | } 170 | } 171 | 172 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/UnitTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeFixes; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using System; 5 | using TestHelper; 6 | using BitFieldsAnalyzer; 7 | using Xunit; 8 | using System.Collections.Generic; 9 | using Microsoft.CodeAnalysis.CodeActions; 10 | using System.Threading; 11 | 12 | namespace BitFieldsAnalyzer.Test 13 | { 14 | public class UnitTest : DiagnosticVerifier 15 | { 16 | [Fact] 17 | public void TestMethod0() 18 | { 19 | var test = @" 20 | class Program 21 | { 22 | static void Main() 23 | { 24 | Bit1 x = 1; 25 | x = 0b100; 26 | x = 0xA; 27 | 28 | (Bit2 a1, Bit3 b1) = (-1, - 2); 29 | (Bit2 a, Bit3 b) = (1, 2); 30 | } 31 | 32 | Bit4 x = 1UL; 33 | Bit5 y = 4; 34 | 35 | Bit6 X { get; } = 1U; 36 | Bit7 Y { get; } = 2L; 37 | 38 | void A() 39 | { 40 | A(1); 41 | A(2); 42 | } 43 | void A(Bit8 x) { } 44 | Bit9 F() => 2; 45 | Bit10 Z => 2; 46 | Bit11 Z1 { get => 2; } 47 | Bit12 Z2 { get { return 2; } } 48 | } 49 | 50 | internal struct Bit1 { public static implicit operator Bit1(int x) => default(Bit1); } 51 | internal struct Bit2 { public static implicit operator Bit2(int x) => default(Bit2); } 52 | internal struct Bit3 { public static implicit operator Bit3(int x) => default(Bit3); } 53 | internal struct Bit4 { public static implicit operator Bit4(int x) => default(Bit4); } 54 | internal struct Bit5 { public static implicit operator Bit5(int x) => default(Bit5); } 55 | internal struct Bit6 { public static implicit operator Bit6(int x) => default(Bit6); } 56 | internal struct Bit7 { public static implicit operator Bit7(int x) => default(Bit7); } 57 | internal struct Bit8 { public static implicit operator Bit8(int x) => default(Bit8); } 58 | internal struct Bit9 { public static implicit operator Bit9(int x) => default(Bit9); } 59 | internal struct Bit11 { public static implicit operator Bit11(int x) => default(Bit11); } 60 | internal struct Bit12 { public static implicit operator Bit12(int x) => default(Bit12); } 61 | internal struct Bit13 { public static implicit operator Bit13(int x) => default(Bit13); } 62 | internal struct Bit14 { public static implicit operator Bit14(int x) => default(Bit14); } 63 | internal struct Bit15 { public static implicit operator Bit15(int x) => default(Bit15); } 64 | internal struct Bit16 { public static implicit operator Bit16(int x) => default(Bit16); } 65 | internal struct Bit17 { public static implicit operator Bit17(int x) => default(Bit17); } 66 | internal struct Bit18 { public static implicit operator Bit18(int x) => default(Bit18); } 67 | internal struct Bit19 { public static implicit operator Bit19(int x) => default(Bit19); } 68 | "; 69 | 70 | var diagnostics = GetSortedDiagnostics(new[] { test }, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer()); 71 | 72 | } 73 | 74 | #if false 75 | 76 | //No diagnostics expected to show up 77 | [Fact] 78 | public void TestMethod1() 79 | { 80 | var test = @""; 81 | 82 | VerifyCSharpDiagnostic(test); 83 | } 84 | 85 | //Diagnostic and CodeFix both triggered and checked for 86 | [Fact] 87 | public void TestMethod2() 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 TypeName 100 | { 101 | } 102 | }"; 103 | var expected = new DiagnosticResult 104 | { 105 | Id = "BitFieldsAnalyzer", 106 | Message = String.Format("Type name '{0}' contains lowercase letters", "TypeName"), 107 | Severity = DiagnosticSeverity.Warning, 108 | Locations = 109 | new[] { 110 | new DiagnosticResultLocation("Test0.cs", 11, 15) 111 | } 112 | }; 113 | 114 | VerifyCSharpDiagnostic(test, expected); 115 | 116 | var fixtest = @" 117 | using System; 118 | using System.Collections.Generic; 119 | using System.Linq; 120 | using System.Text; 121 | using System.Threading.Tasks; 122 | using System.Diagnostics; 123 | 124 | namespace ConsoleApplication1 125 | { 126 | class TYPENAME 127 | { 128 | } 129 | }"; 130 | VerifyCSharpFix(test, fixtest); 131 | } 132 | 133 | #endif 134 | protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() 135 | { 136 | return new BitNAnalyzer(); 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/Verifiers/CodeFixVerifier.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CodeActions; 3 | using Microsoft.CodeAnalysis.CodeFixes; 4 | using Microsoft.CodeAnalysis.Diagnostics; 5 | using Microsoft.CodeAnalysis.Formatting; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading; 9 | using Xunit; 10 | 11 | namespace TestHelper 12 | { 13 | /// 14 | /// Superclass of all Unit tests made for diagnostics with codefixes. 15 | /// Contains methods used to verify correctness of codefixes 16 | /// 17 | public abstract partial class CodeFixVerifier : DiagnosticVerifier 18 | { 19 | /// 20 | /// Returns the codefix being tested (C#) - to be implemented in non-abstract class 21 | /// 22 | /// The CodeFixProvider to be used for CSharp code 23 | protected virtual CodeFixProvider GetCSharpCodeFixProvider() 24 | { 25 | return null; 26 | } 27 | 28 | /// 29 | /// Returns the codefix being tested (VB) - to be implemented in non-abstract class 30 | /// 31 | /// The CodeFixProvider to be used for VisualBasic code 32 | protected virtual CodeFixProvider GetBasicCodeFixProvider() 33 | { 34 | return null; 35 | } 36 | 37 | /// 38 | /// Called to test a C# codefix when applied on the inputted string as a source 39 | /// 40 | /// A class in the form of a string before the CodeFix was applied to it 41 | /// A class in the form of a string after the CodeFix was applied to it 42 | /// Index determining which codefix to apply if there are multiple 43 | /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied 44 | protected void VerifyCSharpFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) 45 | { 46 | VerifyFix(LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), GetCSharpCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics); 47 | } 48 | 49 | /// 50 | /// Called to test a VB codefix when applied on the inputted string as a source 51 | /// 52 | /// A class in the form of a string before the CodeFix was applied to it 53 | /// A class in the form of a string after the CodeFix was applied to it 54 | /// Index determining which codefix to apply if there are multiple 55 | /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied 56 | protected void VerifyBasicFix(string oldSource, string newSource, int? codeFixIndex = null, bool allowNewCompilerDiagnostics = false) 57 | { 58 | VerifyFix(LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), GetBasicCodeFixProvider(), oldSource, newSource, codeFixIndex, allowNewCompilerDiagnostics); 59 | } 60 | 61 | /// 62 | /// General verifier for codefixes. 63 | /// Creates a Document from the source string, then gets diagnostics on it and applies the relevant codefixes. 64 | /// Then gets the string after the codefix is applied and compares it with the expected result. 65 | /// Note: If any codefix causes new diagnostics to show up, the test fails unless allowNewCompilerDiagnostics is set to true. 66 | /// 67 | /// The language the source code is in 68 | /// The analyzer to be applied to the source code 69 | /// The codefix to be applied to the code wherever the relevant Diagnostic is found 70 | /// A class in the form of a string before the CodeFix was applied to it 71 | /// A class in the form of a string after the CodeFix was applied to it 72 | /// Index determining which codefix to apply if there are multiple 73 | /// A bool controlling whether or not the test will fail if the CodeFix introduces other warnings after being applied 74 | private void VerifyFix(string language, DiagnosticAnalyzer analyzer, CodeFixProvider codeFixProvider, string oldSource, string newSource, int? codeFixIndex, bool allowNewCompilerDiagnostics) 75 | { 76 | var document = CreateDocument(oldSource, language); 77 | var analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); 78 | var compilerDiagnostics = GetCompilerDiagnostics(document); 79 | var attempts = analyzerDiagnostics.Length; 80 | 81 | for (int i = 0; i < attempts; ++i) 82 | { 83 | var actions = new List(); 84 | var context = new CodeFixContext(document, analyzerDiagnostics[0], (a, d) => actions.Add(a), CancellationToken.None); 85 | codeFixProvider.RegisterCodeFixesAsync(context).Wait(); 86 | 87 | if (!actions.Any()) 88 | { 89 | break; 90 | } 91 | 92 | if (codeFixIndex != null) 93 | { 94 | document = ApplyFix(document, actions.ElementAt((int)codeFixIndex)); 95 | break; 96 | } 97 | 98 | document = ApplyFix(document, actions.ElementAt(0)); 99 | analyzerDiagnostics = GetSortedDiagnosticsFromDocuments(analyzer, new[] { document }); 100 | 101 | var newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); 102 | 103 | //check if applying the code fix introduced any new compiler diagnostics 104 | if (!allowNewCompilerDiagnostics && newCompilerDiagnostics.Any()) 105 | { 106 | // Format and get the compiler diagnostics again so that the locations make sense in the output 107 | document = document.WithSyntaxRoot(Formatter.Format(document.GetSyntaxRootAsync().Result, Formatter.Annotation, document.Project.Solution.Workspace)); 108 | newCompilerDiagnostics = GetNewDiagnostics(compilerDiagnostics, GetCompilerDiagnostics(document)); 109 | 110 | Assert.True(false, 111 | string.Format("Fix introduced new compiler diagnostics:\r\n{0}\r\n\r\nNew document:\r\n{1}\r\n", 112 | string.Join("\r\n", newCompilerDiagnostics.Select(d => d.ToString())), 113 | document.GetSyntaxRootAsync().Result.ToFullString())); 114 | } 115 | 116 | //check if there are analyzer diagnostics left after the code fix 117 | if (!analyzerDiagnostics.Any()) 118 | { 119 | break; 120 | } 121 | } 122 | 123 | //after applying all of the code fixes, compare the resulting string to the inputted one 124 | var actual = GetStringFromDocument(document); 125 | Assert.Equal(newSource, actual); 126 | } 127 | } 128 | } -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Test/Verifiers/DiagnosticVerifier.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.Diagnostics; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using Xunit; 8 | 9 | namespace TestHelper 10 | { 11 | /// 12 | /// Superclass of all Unit Tests for DiagnosticAnalyzers 13 | /// 14 | public abstract partial class DiagnosticVerifier 15 | { 16 | #region To be implemented by Test classes 17 | /// 18 | /// Get the CSharp analyzer being tested - to be implemented in non-abstract class 19 | /// 20 | protected virtual DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer() 21 | { 22 | return null; 23 | } 24 | 25 | /// 26 | /// Get the Visual Basic analyzer being tested (C#) - to be implemented in non-abstract class 27 | /// 28 | protected virtual DiagnosticAnalyzer GetBasicDiagnosticAnalyzer() 29 | { 30 | return null; 31 | } 32 | #endregion 33 | 34 | #region Verifier wrappers 35 | 36 | /// 37 | /// Called to test a C# DiagnosticAnalyzer when applied on the single inputted string as a source 38 | /// Note: input a DiagnosticResult for each Diagnostic expected 39 | /// 40 | /// A class in the form of a string to run the analyzer on 41 | /// DiagnosticResults that should appear after the analyzer is run on the source 42 | protected void VerifyCSharpDiagnostic(string source, params DiagnosticResult[] expected) 43 | { 44 | VerifyDiagnostics(new[] { source }, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); 45 | } 46 | 47 | /// 48 | /// Called to test a VB DiagnosticAnalyzer when applied on the single inputted string as a source 49 | /// Note: input a DiagnosticResult for each Diagnostic expected 50 | /// 51 | /// A class in the form of a string to run the analyzer on 52 | /// DiagnosticResults that should appear after the analyzer is run on the source 53 | protected void VerifyBasicDiagnostic(string source, params DiagnosticResult[] expected) 54 | { 55 | VerifyDiagnostics(new[] { source }, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); 56 | } 57 | 58 | /// 59 | /// Called to test a C# DiagnosticAnalyzer when applied on the inputted strings as a source 60 | /// Note: input a DiagnosticResult for each Diagnostic expected 61 | /// 62 | /// An array of strings to create source documents from to run the analyzers on 63 | /// DiagnosticResults that should appear after the analyzer is run on the sources 64 | protected void VerifyCSharpDiagnostic(string[] sources, params DiagnosticResult[] expected) 65 | { 66 | VerifyDiagnostics(sources, LanguageNames.CSharp, GetCSharpDiagnosticAnalyzer(), expected); 67 | } 68 | 69 | /// 70 | /// Called to test a VB DiagnosticAnalyzer when applied on the inputted strings as a source 71 | /// Note: input a DiagnosticResult for each Diagnostic expected 72 | /// 73 | /// An array of strings to create source documents from to run the analyzers on 74 | /// DiagnosticResults that should appear after the analyzer is run on the sources 75 | protected void VerifyBasicDiagnostic(string[] sources, params DiagnosticResult[] expected) 76 | { 77 | VerifyDiagnostics(sources, LanguageNames.VisualBasic, GetBasicDiagnosticAnalyzer(), expected); 78 | } 79 | 80 | /// 81 | /// General method that gets a collection of actual diagnostics found in the source after the analyzer is run, 82 | /// then verifies each of them. 83 | /// 84 | /// An array of strings to create source documents from to run the analyzers on 85 | /// The language of the classes represented by the source strings 86 | /// The analyzer to be run on the source code 87 | /// DiagnosticResults that should appear after the analyzer is run on the sources 88 | private void VerifyDiagnostics(string[] sources, string language, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expected) 89 | { 90 | var diagnostics = GetSortedDiagnostics(sources, language, analyzer); 91 | VerifyDiagnosticResults(diagnostics, analyzer, expected); 92 | } 93 | 94 | #endregion 95 | 96 | #region Actual comparisons and verifications 97 | /// 98 | /// Checks each of the actual Diagnostics found and compares them with the corresponding DiagnosticResult in the array of expected results. 99 | /// Diagnostics are considered equal only if the DiagnosticResultLocation, Id, Severity, and Message of the DiagnosticResult match the actual diagnostic. 100 | /// 101 | /// The Diagnostics found by the compiler after running the analyzer on the source code 102 | /// The analyzer that was being run on the sources 103 | /// Diagnostic Results that should have appeared in the code 104 | private static void VerifyDiagnosticResults(IEnumerable actualResults, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expectedResults) 105 | { 106 | int expectedCount = expectedResults.Count(); 107 | int actualCount = actualResults.Count(); 108 | 109 | if (expectedCount != actualCount) 110 | { 111 | string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : " NONE."; 112 | 113 | Assert.True(false, 114 | string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput)); 115 | } 116 | 117 | for (int i = 0; i < expectedResults.Length; i++) 118 | { 119 | var actual = actualResults.ElementAt(i); 120 | var expected = expectedResults[i]; 121 | 122 | if (expected.Line == -1 && expected.Column == -1) 123 | { 124 | if (actual.Location != Location.None) 125 | { 126 | Assert.True(false, 127 | string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}", 128 | FormatDiagnostics(analyzer, actual))); 129 | } 130 | } 131 | else 132 | { 133 | VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Locations.First()); 134 | var additionalLocations = actual.AdditionalLocations.ToArray(); 135 | 136 | if (additionalLocations.Length != expected.Locations.Length - 1) 137 | { 138 | Assert.True(false, 139 | string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n {2}\r\n", 140 | expected.Locations.Length - 1, additionalLocations.Length, 141 | FormatDiagnostics(analyzer, actual))); 142 | } 143 | 144 | for (int j = 0; j < additionalLocations.Length; ++j) 145 | { 146 | VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Locations[j + 1]); 147 | } 148 | } 149 | 150 | if (actual.Id != expected.Id) 151 | { 152 | Assert.True(false, 153 | string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 154 | expected.Id, actual.Id, FormatDiagnostics(analyzer, actual))); 155 | } 156 | 157 | if (actual.Severity != expected.Severity) 158 | { 159 | Assert.True(false, 160 | string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 161 | expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual))); 162 | } 163 | 164 | if (actual.GetMessage() != expected.Message) 165 | { 166 | Assert.True(false, 167 | string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 168 | expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual))); 169 | } 170 | } 171 | } 172 | 173 | /// 174 | /// Helper method to VerifyDiagnosticResult that checks the location of a diagnostic and compares it with the location in the expected DiagnosticResult. 175 | /// 176 | /// The analyzer that was being run on the sources 177 | /// The diagnostic that was found in the code 178 | /// The Location of the Diagnostic found in the code 179 | /// The DiagnosticResultLocation that should have been found 180 | private static void VerifyDiagnosticLocation(DiagnosticAnalyzer analyzer, Diagnostic diagnostic, Location actual, DiagnosticResultLocation expected) 181 | { 182 | var actualSpan = actual.GetLineSpan(); 183 | 184 | Assert.True(actualSpan.Path == expected.Path || (actualSpan.Path != null && actualSpan.Path.Contains("Test0.") && expected.Path.Contains("Test.")), 185 | string.Format("Expected diagnostic to be in file \"{0}\" was actually in file \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 186 | expected.Path, actualSpan.Path, FormatDiagnostics(analyzer, diagnostic))); 187 | 188 | var actualLinePosition = actualSpan.StartLinePosition; 189 | 190 | // Only check line position if there is an actual line in the real diagnostic 191 | if (actualLinePosition.Line > 0) 192 | { 193 | if (actualLinePosition.Line + 1 != expected.Line) 194 | { 195 | Assert.True(false, 196 | string.Format("Expected diagnostic to be on line \"{0}\" was actually on line \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 197 | expected.Line, actualLinePosition.Line + 1, FormatDiagnostics(analyzer, diagnostic))); 198 | } 199 | } 200 | 201 | // Only check column position if there is an actual column position in the real diagnostic 202 | if (actualLinePosition.Character > 0) 203 | { 204 | if (actualLinePosition.Character + 1 != expected.Column) 205 | { 206 | Assert.True(false, 207 | string.Format("Expected diagnostic to start at column \"{0}\" was actually at column \"{1}\"\r\n\r\nDiagnostic:\r\n {2}\r\n", 208 | expected.Column, actualLinePosition.Character + 1, FormatDiagnostics(analyzer, diagnostic))); 209 | } 210 | } 211 | } 212 | #endregion 213 | 214 | #region Formatting Diagnostics 215 | /// 216 | /// Helper method to format a Diagnostic into an easily readable string 217 | /// 218 | /// The analyzer that this verifier tests 219 | /// The Diagnostics to be formatted 220 | /// The Diagnostics formatted as a string 221 | private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics) 222 | { 223 | var builder = new StringBuilder(); 224 | for (int i = 0; i < diagnostics.Length; ++i) 225 | { 226 | builder.AppendLine("// " + diagnostics[i].ToString()); 227 | 228 | var analyzerType = analyzer.GetType(); 229 | var rules = analyzer.SupportedDiagnostics; 230 | 231 | foreach (var rule in rules) 232 | { 233 | if (rule != null && rule.Id == diagnostics[i].Id) 234 | { 235 | var location = diagnostics[i].Location; 236 | if (location == Location.None) 237 | { 238 | builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id); 239 | } 240 | else 241 | { 242 | Assert.True(location.IsInSource, 243 | $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n"); 244 | 245 | string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt"; 246 | var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; 247 | 248 | builder.AppendFormat("{0}({1}, {2}, {3}.{4})", 249 | resultMethodName, 250 | linePosition.Line + 1, 251 | linePosition.Character + 1, 252 | analyzerType.Name, 253 | rule.Id); 254 | } 255 | 256 | if (i != diagnostics.Length - 1) 257 | { 258 | builder.Append(','); 259 | } 260 | 261 | builder.AppendLine(); 262 | break; 263 | } 264 | } 265 | } 266 | return builder.ToString(); 267 | } 268 | #endregion 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Vsix/BitFieldsAnalyzer.Vsix.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 15.0 6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 7 | 8 | 9 | 14.0 10 | 11 | publish\ 12 | true 13 | Disk 14 | false 15 | Foreground 16 | 7 17 | Days 18 | false 19 | false 20 | true 21 | 0 22 | 1.0.0.%2a 23 | false 24 | false 25 | true 26 | 27 | 28 | 29 | 30 | Debug 31 | AnyCPU 32 | AnyCPU 33 | 2.0 34 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 35 | {5106E44E-D56B-4654-8D6A-9F6B782DB09D} 36 | Library 37 | Properties 38 | BitFieldsAnalyzer.Vsix 39 | BitFieldsAnalyzer.Vsix 40 | v4.6.2 41 | false 42 | false 43 | false 44 | false 45 | false 46 | false 47 | Roslyn 48 | 49 | 50 | true 51 | full 52 | false 53 | bin\Debug\ 54 | DEBUG;TRACE 55 | prompt 56 | 4 57 | 58 | 59 | pdbonly 60 | true 61 | bin\Release\ 62 | TRACE 63 | prompt 64 | 4 65 | 66 | 67 | Program 68 | $(DevEnvDir)devenv.exe 69 | /rootsuffix Roslyn 70 | 71 | 72 | 73 | Designer 74 | 75 | 76 | 77 | 78 | {EE4CFF3F-5F05-44B6-A12D-AB0BA23D1BF1} 79 | BitFieldsAnalyzer 80 | 81 | 82 | 83 | 84 | False 85 | .NET Framework 3.5 SP1 86 | false 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer.Vsix/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | BitFieldsAnalyzer 6 | This is a sample diagnostic extension for the .NET Compiler Platform ("Roslyn"). 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/BitField.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace BitFieldsAnalyzer 6 | { 7 | struct BitField 8 | { 9 | public string Name; 10 | public int StartBit; 11 | public int EndBit; 12 | 13 | public BitField(string name, int start, int end) => (Name, StartBit, EndBit) = (name, start, end); 14 | public void Deconstruct(out string name, out int start, out int end, out int bits) => (name, start, end, bits) = (Name, StartBit, EndBit, Bits); 15 | 16 | public static IEnumerable Create(IEnumerable<(string name, int bits)> items) 17 | { 18 | var start = 0; 19 | foreach (var (name, bits) in items) 20 | { 21 | var end = start + bits; 22 | yield return new BitField(name, start, end); 23 | start = end; 24 | } 25 | } 26 | public int Bits => EndBit - StartBit; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/BitFieldGeneratorAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using Microsoft.CodeAnalysis.Diagnostics; 6 | using System.Linq; 7 | 8 | namespace BitFieldsAnalyzer 9 | { 10 | [DiagnosticAnalyzer(LanguageNames.CSharp)] 11 | public class BitFieldGeneratorAnalyzer : DiagnosticAnalyzer 12 | { 13 | public const string DiagnosticId = "BitFieldGenerator"; 14 | 15 | // You can change these strings in the Resources.resx file. If you do not want your analyzer to be localize-able, you can use regular strings for Title and MessageFormat. 16 | // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Localizing%20Analyzers.md for more on localization 17 | private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.BitFieldGeneratorAnalyzerTitle), Resources.ResourceManager, typeof(Resources)); 18 | private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.BitFieldGeneratorAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); 19 | private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.BitFieldGeneratorAnalyzerDescription), Resources.ResourceManager, typeof(Resources)); 20 | private const string Category = "Syntax"; 21 | 22 | private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Info, isEnabledByDefault: true, description: Description); 23 | 24 | public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } } 25 | 26 | public override void Initialize(AnalysisContext context) 27 | { 28 | context.RegisterSyntaxNodeAction(AnalyzerSyntax, SyntaxKind.EnumDeclaration); 29 | } 30 | 31 | private void AnalyzerSyntax(SyntaxNodeAnalysisContext context) 32 | { 33 | var s = context.Node as EnumDeclarationSyntax; 34 | var parent = s.FirstAncestorOrSelf(); 35 | 36 | if (parent == null) return; 37 | 38 | var name = s.Identifier.Text; 39 | if (name != "BitFields") return; 40 | 41 | if (!parent.ChildNodes().Any(n => n == s)) 42 | return; 43 | 44 | var diagnostic = Diagnostic.Create(Rule, s.GetLocation(), parent.Identifier.Text); 45 | context.ReportDiagnostic(diagnostic); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/BitFieldGeneratorCodeFixProvider.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using System.Composition; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Microsoft.CodeAnalysis; 7 | using Microsoft.CodeAnalysis.CodeFixes; 8 | using Microsoft.CodeAnalysis.CodeActions; 9 | using Microsoft.CodeAnalysis.CSharp; 10 | using Microsoft.CodeAnalysis.CSharp.Syntax; 11 | using Microsoft.CodeAnalysis.Rename; 12 | using Microsoft.CodeAnalysis.Formatting; 13 | using System; 14 | using System.Collections.Generic; 15 | using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; 16 | 17 | namespace BitFieldsAnalyzer 18 | { 19 | [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(BitFieldGeneratorCodeFixProvider)), Shared] 20 | public class BitFieldGeneratorCodeFixProvider : CodeFixProvider 21 | { 22 | private const string title = "Generate bit-fields"; 23 | 24 | public sealed override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(BitFieldGeneratorAnalyzer.DiagnosticId); 25 | public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; 26 | 27 | public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) 28 | { 29 | var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); 30 | 31 | // TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest 32 | var diagnostic = context.Diagnostics.First(); 33 | var diagnosticSpan = diagnostic.Location.SourceSpan; 34 | 35 | // Find the type declaration identified by the diagnostic. 36 | var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType().First(); 37 | 38 | // Register a code action that will invoke the fix. 39 | context.RegisterCodeFix( 40 | CodeAction.Create( 41 | title: title, 42 | createChangedSolution: c => GenerateBitFieldAsync(context.Document, declaration, c), 43 | equivalenceKey: title), 44 | diagnostic); 45 | } 46 | 47 | private async Task GenerateBitFieldAsync(Document document, StructDeclarationSyntax typeDecl, CancellationToken cancellationToken) 48 | { 49 | document = await AddPartialModifier(document, typeDecl, cancellationToken); 50 | document = await AddNewDocument(document, typeDecl, cancellationToken); 51 | 52 | return document.Project.Solution; 53 | } 54 | 55 | private static async Task AddPartialModifier(Document document, StructDeclarationSyntax typeDecl, CancellationToken cancellationToken) 56 | { 57 | var newTypeDecl = typeDecl.AddPartialModifier(); 58 | 59 | var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; 60 | var newRoolt = root.ReplaceNode(typeDecl, newTypeDecl) 61 | .WithAdditionalAnnotations(Formatter.Annotation); 62 | 63 | document = document.WithSyntaxRoot(newRoolt); 64 | return document; 65 | } 66 | 67 | private static async Task AddNewDocument(Document document, StructDeclarationSyntax typeDecl, CancellationToken cancellationToken) 68 | { 69 | var newRoot = await GeneratePartialDeclaration(document, typeDecl, cancellationToken); 70 | 71 | var xxx = newRoot.ToString(); 72 | 73 | var name = typeDecl.Identifier.Text; 74 | var generatedName = name + ".BitFields.cs"; 75 | 76 | var project = document.Project; 77 | 78 | var existed = project.Documents.FirstOrDefault(d => d.Name == generatedName); 79 | if (existed != null) return existed.WithSyntaxRoot(newRoot); 80 | else return project.AddDocument(generatedName, newRoot, document.Folders); 81 | } 82 | 83 | private static async Task GeneratePartialDeclaration(Document document, StructDeclarationSyntax typeDecl, CancellationToken cancellationToken) 84 | { 85 | var definition = typeDecl.ChildNodes().OfType().FirstOrDefault(n => n.Identifier.Text == "BitFields"); 86 | var bitfields = BitField.Create(f()).ToArray(); 87 | 88 | IEnumerable<(string name, int bits)> f() 89 | { 90 | foreach (var m in definition.Members) 91 | { 92 | if (m.EqualsValue.Value is LiteralExpressionSyntax literal) 93 | { 94 | yield return (m.Identifier.Text, (int)Util.GetNumber(literal.Token.Value)); 95 | } 96 | } 97 | } 98 | 99 | var generatedNodes = GenerateMemberDeclarations(bitfields).ToArray(); 100 | 101 | var newTypeDecl = typeDecl.GetPartialTypeDelaration() 102 | .AddMembers(generatedNodes) 103 | .WithAdditionalAnnotations(Formatter.Annotation); 104 | 105 | var ns = typeDecl.FirstAncestorOrSelf()?.Name.WithoutTrivia().GetText().ToString(); 106 | 107 | MemberDeclarationSyntax topDecl; 108 | if (ns != null) 109 | { 110 | topDecl = NamespaceDeclaration(IdentifierName(ns)) 111 | .AddMembers(newTypeDecl) 112 | .WithAdditionalAnnotations(Formatter.Annotation); 113 | } 114 | else 115 | { 116 | topDecl = newTypeDecl; 117 | } 118 | 119 | var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false) as CompilationUnitSyntax; 120 | 121 | return CompilationUnit() 122 | .AddUsings(UsingDirective(IdentifierName("BitFields")).WithTrailingTrivia(CarriageReturnLineFeed)) 123 | .AddMembers(topDecl) 124 | .WithTrailingTrivia(CarriageReturnLineFeed) 125 | .WithAdditionalAnnotations(Formatter.Annotation); 126 | } 127 | 128 | private static IEnumerable GenerateMemberDeclarations(BitField[] bitfields) 129 | { 130 | var totalBits = bitfields.Last().EndBit; 131 | var fieldType = Util.GetCapableType(totalBits); 132 | 133 | yield return CSharpSyntaxTree.ParseText( 134 | $@" public {fieldType} Value; 135 | ").GetRoot().ChildNodes() 136 | .OfType() 137 | .First() 138 | .WithTrailingTrivia(CarriageReturnLineFeed, CarriageReturnLineFeed) 139 | .WithAdditionalAnnotations(Formatter.Annotation) 140 | ; 141 | 142 | var postfix = fieldType == "ulong" ? "UL" : "U"; 143 | 144 | foreach (var (name, start, end, bits) in bitfields) 145 | { 146 | var childNodes = CSharpSyntaxTree.ParseText( 147 | $@" private const int {name}Shift = {start}; 148 | private const {fieldType} {name}Mask = unchecked(({fieldType})((1{postfix} << {end}) - (1{postfix} << {start}))); 149 | public Bit{bits} {name} 150 | {{ 151 | get => (Bit{bits})((Value & {name}Mask) >> {name}Shift); 152 | set => Value = unchecked(({fieldType})((Value & ~{name}Mask) | (((({fieldType})value) << {name}Shift) & {name}Mask))); 153 | }} 154 | ") 155 | .GetRoot().ChildNodes() 156 | .OfType() 157 | .Select(n => n 158 | .WithTrailingTrivia(CarriageReturnLineFeed) 159 | .WithAdditionalAnnotations(Formatter.Annotation) 160 | ); 161 | 162 | foreach (var n in childNodes) yield return n; 163 | } 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/BitFieldsAnalyzer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Library 4 | BitFieldsAnalyzer 5 | BitFieldsAnalyzer 6 | netstandard1.4 7 | $(PackageTargetFallback);portable-net45+win8+wp8+wpa81 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/BitNAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Immutable; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using Microsoft.CodeAnalysis.Diagnostics; 6 | 7 | namespace BitFieldsAnalyzer 8 | { 9 | [DiagnosticAnalyzer(LanguageNames.CSharp)] 10 | public class BitNAnalyzer : DiagnosticAnalyzer 11 | { 12 | public const string DiagnosticId = "BitNAnalyzer"; 13 | 14 | // You can change these strings in the Resources.resx file. If you do not want your analyzer to be localize-able, you can use regular strings for Title and MessageFormat. 15 | // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Localizing%20Analyzers.md for more on localization 16 | private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.BitNAnalyzerTitle), Resources.ResourceManager, typeof(Resources)); 17 | private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.BitNAnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources)); 18 | private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.BitNAnalyzerDescription), Resources.ResourceManager, typeof(Resources)); 19 | private const string Category = "Syntax"; 20 | 21 | private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description); 22 | 23 | public override ImmutableArray SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } } 24 | 25 | public override void Initialize(AnalysisContext context) 26 | { 27 | context.RegisterSyntaxNodeAction(AnalyzerNumericAction, SyntaxKind.NumericLiteralExpression); 28 | } 29 | 30 | private void AnalyzerNumericAction(SyntaxNodeAnalysisContext obj) 31 | { 32 | var node = (LiteralExpressionSyntax)obj.Node; 33 | var t = obj.SemanticModel.GetTypeInfo(node); 34 | var typeName = t.ConvertedType.Name; 35 | 36 | if(Util.MatchName(typeName) is int bits) 37 | { 38 | var num = Util.GetNumber(node.Token.Value); 39 | var dig = Util.Log2(num); 40 | 41 | if (dig > bits) 42 | { 43 | obj.ReportDiagnostic(Diagnostic.Create(Rule, node.GetLocation(), node.Token.Text, typeName)); 44 | } 45 | else 46 | { 47 | 48 | } 49 | } 50 | else 51 | { 52 | //todo: UnaryPlus + Literal: -) 53 | //todo: UnaryMinus + Literal: -) 54 | //todo: Cast + Literal: (byte)1 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/Diagnostic.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | BitFieldsAnalyzer 5 | 1.0.0.0 6 | BitFieldsAnalyzer 7 | xii-h 8 | xii-h 9 | http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE 10 | http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE 11 | http://ICON_URL_HERE_OR_DELETE_THIS_LINE 12 | false 13 | BitFieldsAnalyzer 14 | Summary of changes made in this release of the package. 15 | Copyright 16 | BitFieldsAnalyzer, analyzers 17 | 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/ReadMe.txt: -------------------------------------------------------------------------------- 1 |  2 | Building this project will produce an analyzer .dll, as well as the 3 | following two ways you may wish to package that analyzer: 4 | * A NuGet package (.nupkg file) that will add your assembly as a 5 | project-local analyzer that participates in builds. 6 | * A VSIX extension (.vsix file) that will apply your analyzer to all projects 7 | and works just in the IDE. 8 | 9 | To debug your analyzer, make sure the default project is the VSIX project and 10 | start debugging. This will deploy the analyzer as a VSIX into another instance 11 | of Visual Studio, which is useful for debugging, even if you intend to produce 12 | a NuGet package. 13 | 14 | 15 | TRYING OUT YOUR NUGET PACKAGE 16 | 17 | To try out the NuGet package: 18 | 1. Create a local NuGet feed by following the instructions here: 19 | > http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds 20 | 2. Copy the .nupkg file into that folder. 21 | 3. Open the target project in Visual Studio 2015. 22 | 4. Right-click on the project node in Solution Explorer and choose Manage 23 | NuGet Packages. 24 | 5. Select the NuGet feed you created on the left. 25 | 6. Choose your analyzer from the list and click Install. 26 | 27 | If you want to automatically deploy the .nupkg file to the local feed folder 28 | when you build this project, follow these steps: 29 | 1. Right-click on this project in Solution Explorer and choose 'Unload Project'. 30 | 2. Right-click on this project and click "Edit". 31 | 3. Scroll down to the "AfterBuild" target. 32 | 4. In the "Exec" task, change the value inside "Command" after the -OutputDirectory 33 | path to point to your local NuGet feed folder. -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 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 BitFieldsAnalyzer 12 | { 13 | using System; 14 | using System.Reflection; 15 | 16 | 17 | /// 18 | /// A strongly-typed resource class, for looking up localized strings, etc. 19 | /// 20 | // This class was auto-generated by the StronglyTypedResourceBuilder 21 | // class via a tool like ResGen or Visual Studio. 22 | // To add or remove a member, edit your .ResX file then rerun ResGen 23 | // with the /str option, or rebuild your VS project. 24 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 25 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 26 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 27 | internal class Resources 28 | { 29 | 30 | private static global::System.Resources.ResourceManager resourceMan; 31 | 32 | private static global::System.Globalization.CultureInfo resourceCulture; 33 | 34 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 35 | internal Resources() 36 | { 37 | } 38 | 39 | /// 40 | /// Returns the cached ResourceManager instance used by this class. 41 | /// 42 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 43 | internal static global::System.Resources.ResourceManager ResourceManager 44 | { 45 | get 46 | { 47 | if (object.ReferenceEquals(resourceMan, null)) 48 | { 49 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BitFieldsAnalyzer.Resources", typeof(Resources).GetTypeInfo().Assembly); 50 | resourceMan = temp; 51 | } 52 | return resourceMan; 53 | } 54 | } 55 | 56 | /// 57 | /// Overrides the current thread's CurrentUICulture property for all 58 | /// resource lookups using this strongly typed resource class. 59 | /// 60 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 61 | internal static global::System.Globalization.CultureInfo Culture 62 | { 63 | get 64 | { 65 | return resourceCulture; 66 | } 67 | set 68 | { 69 | resourceCulture = value; 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized string similar to Type names should be all uppercase.. 75 | /// 76 | internal static string BitNAnalyzerDescription 77 | { 78 | get 79 | { 80 | return ResourceManager.GetString("BitNAnalyzerDescription", resourceCulture); 81 | } 82 | } 83 | 84 | /// 85 | /// Looks up a localized string similar to Type name '{0}' contains lowercase letters. 86 | /// 87 | internal static string BitNAnalyzerMessageFormat 88 | { 89 | get 90 | { 91 | return ResourceManager.GetString("BitNAnalyzerMessageFormat", resourceCulture); 92 | } 93 | } 94 | 95 | /// 96 | /// Looks up a localized string similar to Type name contains lowercase letters. 97 | /// 98 | internal static string BitNAnalyzerTitle 99 | { 100 | get 101 | { 102 | return ResourceManager.GetString("BitNAnalyzerTitle", resourceCulture); 103 | } 104 | } 105 | 106 | /// 107 | /// 108 | internal static string BitFieldGeneratorAnalyzerDescription 109 | { 110 | get 111 | { 112 | return ResourceManager.GetString("BitFieldGeneratorAnalyzerDescription", resourceCulture); 113 | } 114 | } 115 | 116 | /// 117 | /// 118 | internal static string BitFieldGeneratorAnalyzerMessageFormat 119 | { 120 | get 121 | { 122 | return ResourceManager.GetString("BitFieldGeneratorAnalyzerMessageFormat", resourceCulture); 123 | } 124 | } 125 | 126 | /// 127 | /// 128 | internal static string BitFieldGeneratorAnalyzerTitle 129 | { 130 | get 131 | { 132 | return ResourceManager.GetString("BitFieldGeneratorAnalyzerTitle", resourceCulture); 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/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 | You can generate bit-fields. 122 | 123 | 124 | You can generate bit-fields on '{0}'. 125 | 126 | 127 | Bit field generation 128 | 129 | 130 | An attempt was made to assign a value to a variable whose type cannot store the value. 131 | An optional longer localizable description of the diagnostic. 132 | 133 | 134 | Constant value '{0}' cannot be converted to a '{1}' 135 | The format-able message the diagnostic displays. 136 | 137 | 138 | Literal conversion error. 139 | The title of the diagnostic. 140 | 141 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/SyntaxExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; 6 | 7 | namespace BitFieldsAnalyzer 8 | { 9 | static class SyntaxExtensions 10 | { 11 | private static readonly SyntaxToken PartialToken = Token(SyntaxKind.PartialKeyword); 12 | 13 | public static StructDeclarationSyntax AddPartialModifier(this StructDeclarationSyntax typeDecl) 14 | { 15 | if (typeDecl.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword))) return typeDecl; 16 | return typeDecl.AddModifiers(new[] { PartialToken }); 17 | } 18 | 19 | public static StructDeclarationSyntax GetPartialTypeDelaration(this StructDeclarationSyntax typeDecl) 20 | => CSharpSyntaxTree.ParseText($@" 21 | partial struct {typeDecl.Identifier.Text} 22 | {{ 23 | }} 24 | ").GetRoot().ChildNodes().OfType().First(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/BitFieldsAnalyzer/BitFieldsAnalyzer/Util.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using System.Text; 6 | 7 | namespace BitFieldsAnalyzer 8 | { 9 | static class Util 10 | { 11 | /// 12 | /// Match(name, "Bit\d{1,2}") 13 | /// 14 | /// 15 | public static int? MatchName(string name) 16 | { 17 | int matchDig(char c) 18 | { 19 | if ('0' <= c && c <= '9') return c - '0'; 20 | else return -1; 21 | } 22 | 23 | if (name.Length < 4 || name[0] != 'B' || name[1] != 'i' || name[2] != 't') return null; 24 | 25 | var num = 0; 26 | for (int i = 3; i < name.Length; i++) 27 | { 28 | var d = matchDig(name[i]); 29 | if (d < 0) return null; 30 | num = num * 10 + d; 31 | } 32 | return num; 33 | } 34 | 35 | [StructLayout(LayoutKind.Explicit)] 36 | struct Union 37 | { 38 | [FieldOffset(0)] 39 | public ulong Ulong; 40 | [FieldOffset(0)] 41 | public double Double; 42 | } 43 | 44 | /// 45 | /// 46 | /// 47 | /// 48 | public static int Log2(ulong value) 49 | { 50 | var u = default(Union); 51 | u.Double = value + 0.5; 52 | return 32 - 1054 + (int)(u.Ulong >> 52); 53 | } 54 | 55 | public static string GetCapableType(int bits) 56 | { 57 | if (bits <= 8) return "byte"; 58 | if (bits <= 16) return "ushort"; 59 | if (bits <= 32) return "uint"; 60 | if (bits <= 64) return "ulong"; 61 | throw new IndexOutOfRangeException(); 62 | } 63 | 64 | public static ulong GetNumber(object obj) 65 | { 66 | switch (obj) 67 | { 68 | case int x: return (ulong)x; 69 | case uint x: return x; 70 | case long x: return (ulong)x; 71 | case ulong x: return x; 72 | case short x: return (ulong)x; 73 | case ushort x: return x; 74 | case sbyte x: return (ulong)x; 75 | case byte x: return x; 76 | default: throw new NotSupportedException(); 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/pack.bat: -------------------------------------------------------------------------------- 1 | .\nuget.exe pack 2 | -------------------------------------------------------------------------------- /src/restore.ps1: -------------------------------------------------------------------------------- 1 | Invoke-WebRequest http://nuget.org/nuget.exe -OutFile nuget.exe -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojNet35/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNewCsprojNet35 4 | { 5 | struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | public class Class1 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojNet35/ClassLibraryNewCsprojNet35.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net35 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojNet462/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNewCsprojNet462 4 | { 5 | partial struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | public class Class1 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojNet462/ClassLibraryNewCsprojNet462.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net462 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojNet462/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ClassLibraryNewCsprojNet462 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd10/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNewCsprojStd10 4 | { 5 | partial struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | public class Class1 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd10/ClassLibraryNewCsprojStd10.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd10/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ClassLibraryNewCsprojStd10 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd14/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNewCsprojStd14 4 | { 5 | partial struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | public class Class1 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd14/ClassLibraryNewCsprojStd14.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.4 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd14/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ClassLibraryNewCsprojStd14 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd16/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ClassLibraryNewCsprojStd16 4 | { 5 | partial struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | public class Class1 11 | { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd16/ClassLibraryNewCsprojStd16.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard1.4 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryNewCsprojStd16/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ClassLibraryNewCsprojStd16 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet35/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ClassLibraryOldCsprojNet35 7 | { 8 | struct Flags 9 | { 10 | enum BitFields { A = 1, B = 1, C = 1 } 11 | } 12 | 13 | public class Class1 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet35/ClassLibraryOldCsprojNet35.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F7CC885B-39F3-4B37-984D-31B2D47AD984} 8 | Library 9 | Properties 10 | ClassLibraryOldCsprojNet35 11 | ClassLibraryOldCsprojNet35 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet35/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClassLibraryOldCsprojNet35")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ClassLibraryOldCsprojNet35")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f7cc885b-39f3-4b37-984d-31b2d47ad984")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet462/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ClassLibraryOldCsprojNet462 8 | { 9 | partial struct Flags 10 | { 11 | enum BitFields { A = 1, B = 1, C = 1 } 12 | } 13 | 14 | public class Class1 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet462/ClassLibraryOldCsprojNet462.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {4C2132CF-6FB7-47E6-8275-C1387D7814A1} 8 | Library 9 | Properties 10 | ClassLibraryOldCsprojNet462 11 | ClassLibraryOldCsprojNet462 12 | v4.6.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 0.1.0 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet462/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ClassLibraryOldCsprojNet462 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryOldCsprojNet462/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ClassLibraryOldCsprojNet462")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ClassLibraryOldCsprojNet462")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("4c2132cf-6fb7-47e6-8275-c1387d7814a1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryPcl/Class1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ClassLibraryPcl 7 | { 8 | partial struct Flags 9 | { 10 | enum BitFields { A = 1, B = 1, C = 1 } 11 | } 12 | 13 | public class Class1 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryPcl/ClassLibraryPcl.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 10.0 6 | Debug 7 | AnyCPU 8 | {4DDDE0EF-DDDA-454B-B50A-363BD38E27B6} 9 | Library 10 | ClassLibraryPcl 11 | ClassLibraryPcl 12 | en-US 13 | 512 14 | {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | Profile7 16 | v4.5 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ClassLibraryPcl/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Resources; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("ClassLibraryPcl")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("")] 13 | [assembly: AssemblyProduct("ClassLibraryPcl")] 14 | [assembly: AssemblyCopyright("Copyright © 2017")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | [assembly: NeutralResourcesLanguage("en")] 18 | 19 | // Version information for an assembly consists of the following four values: 20 | // 21 | // Major Version 22 | // Minor Version 23 | // Build Number 24 | // Revision 25 | // 26 | // You can specify all the values or you can default the Build and Revision Numbers 27 | // by using the '*' as shown below: 28 | // [assembly: AssemblyVersion("1.0.*")] 29 | [assembly: AssemblyVersion("1.0.0.0")] 30 | [assembly: AssemblyFileVersion("1.0.0.0")] 31 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppCore/ConsoleAppCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp1.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppCore/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ConsoleAppCore 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppCore/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ConsoleAppCore 4 | { 5 | partial struct Flags 6 | { 7 | enum BitFields { A = 1, B = 1, C = 1 } 8 | } 9 | 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | Console.WriteLine("Hello World!"); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet35/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet35/ConsoleAppNet35.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {997632FF-C939-410F-8797-1AD7B8482F21} 8 | Exe 9 | ConsoleAppNet35 10 | ConsoleAppNet35 11 | v3.5 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet35/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace ConsoleAppNet35 7 | { 8 | struct Flags 9 | { 10 | enum BitFields { A = 1, B = 1, C = 1 } 11 | } 12 | 13 | class Program 14 | { 15 | static void Main(string[] args) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet35/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleAppNet35")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleAppNet35")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("997632ff-c939-410f-8797-1ad7b8482f21")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet4/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet4/ConsoleAppNet4.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {61A44935-53EE-45C0-B7FA-A1CDA43BFF71} 8 | Exe 9 | ConsoleAppNet4 10 | ConsoleAppNet4 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet4/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ConsoleAppNet4 8 | { 9 | struct Flags 10 | { 11 | enum BitFields { A = 1, B = 1, C = 1 } 12 | } 13 | 14 | class Program 15 | { 16 | static void Main(string[] args) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet4/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleAppNet4")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleAppNet4")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("61a44935-53ee-45c0-b7fa-a1cda43bff71")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet45/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet45/ConsoleAppNet45.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0EB97F72-DABA-4E6C-842D-303C3AE91075} 8 | Exe 9 | ConsoleAppNet45 10 | ConsoleAppNet45 11 | v4.5 12 | 512 13 | true 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 0.1.0 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet45/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ConsoleAppNet45 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet45/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ConsoleAppNet45 8 | { 9 | partial struct Flags 10 | { 11 | enum BitFields { A = 1, B = 1, C = 1 } 12 | } 13 | 14 | class Program 15 | { 16 | static void Main(string[] args) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet45/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleAppNet45")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleAppNet45")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0eb97f72-daba-4e6c-842d-303c3ae91075")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet462/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet462/ConsoleAppNet462.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {623680B5-6C19-4159-8C6D-5682FFBB4D5F} 8 | Exe 9 | ConsoleAppNet462 10 | ConsoleAppNet462 11 | v4.6.2 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 0.1.0 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet462/Flags.BitFields.cs: -------------------------------------------------------------------------------- 1 | using BitFields; 2 | 3 | namespace ConsoleAppNet462 4 | { 5 | partial struct Flags 6 | { 7 | public byte Value; 8 | 9 | private const int AShift = 0; 10 | private const byte AMask = unchecked((byte)((1U << 1) - (1U << 0))); 11 | public Bit1 A 12 | { 13 | get => (Bit1)((Value & AMask) >> AShift); 14 | set => Value = unchecked((byte)((Value & ~AMask) | ((((byte)value) << AShift) & AMask))); 15 | } 16 | private const int BShift = 1; 17 | private const byte BMask = unchecked((byte)((1U << 2) - (1U << 1))); 18 | public Bit1 B 19 | { 20 | get => (Bit1)((Value & BMask) >> BShift); 21 | set => Value = unchecked((byte)((Value & ~BMask) | ((((byte)value) << BShift) & BMask))); 22 | } 23 | private const int CShift = 2; 24 | private const byte CMask = unchecked((byte)((1U << 3) - (1U << 2))); 25 | public Bit1 C 26 | { 27 | get => (Bit1)((Value & CMask) >> CShift); 28 | set => Value = unchecked((byte)((Value & ~CMask) | ((((byte)value) << CShift) & CMask))); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet462/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace ConsoleAppNet462 8 | { 9 | partial struct Flags 10 | { 11 | enum BitFields { A = 1, B = 1, C = 1 } 12 | } 13 | 14 | class Program 15 | { 16 | static void Main(string[] args) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/ConsoleAppNet462/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ConsoleAppNet462")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ConsoleAppNet462")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("623680b5-6c19-4159-8c6d-5682ffbb4d5f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /tests/TargetFrameworks/TargetFrameworks.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.7 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet35", "ConsoleAppNet35\ConsoleAppNet35.csproj", "{997632FF-C939-410F-8797-1AD7B8482F21}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet4", "ConsoleAppNet4\ConsoleAppNet4.csproj", "{61A44935-53EE-45C0-B7FA-A1CDA43BFF71}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet45", "ConsoleAppNet45\ConsoleAppNet45.csproj", "{0EB97F72-DABA-4E6C-842D-303C3AE91075}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppNet462", "ConsoleAppNet462\ConsoleAppNet462.csproj", "{623680B5-6C19-4159-8C6D-5682FFBB4D5F}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppCore", "ConsoleAppCore\ConsoleAppCore.csproj", "{C5E17F51-0B21-448A-94FF-6090DA09DBB4}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryOldCsprojNet35", "ClassLibraryOldCsprojNet35\ClassLibraryOldCsprojNet35.csproj", "{F7CC885B-39F3-4B37-984D-31B2D47AD984}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryOldCsprojNet462", "ClassLibraryOldCsprojNet462\ClassLibraryOldCsprojNet462.csproj", "{4C2132CF-6FB7-47E6-8275-C1387D7814A1}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNewCsprojNet35", "ClassLibraryNewCsprojNet35\ClassLibraryNewCsprojNet35.csproj", "{C38DEE73-5240-4F3F-B9FC-4F622380557F}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNewCsprojNet462", "ClassLibraryNewCsprojNet462\ClassLibraryNewCsprojNet462.csproj", "{6CFF5D6A-71DF-4BDF-B6A9-203B78EEF445}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNewCsprojStd10", "ClassLibraryNewCsprojStd10\ClassLibraryNewCsprojStd10.csproj", "{41D4D834-9820-456F-AA68-7BE70F257C62}" 25 | EndProject 26 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNewCsprojStd14", "ClassLibraryNewCsprojStd14\ClassLibraryNewCsprojStd14.csproj", "{431412E3-A0AA-4DCE-86BA-5F6716522890}" 27 | EndProject 28 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryNewCsprojStd16", "ClassLibraryNewCsprojStd16\ClassLibraryNewCsprojStd16.csproj", "{D7FF2B97-9DD4-46C5-BD3D-72F027C6A5F0}" 29 | EndProject 30 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibraryPcl", "ClassLibraryPcl\ClassLibraryPcl.csproj", "{4DDDE0EF-DDDA-454B-B50A-363BD38E27B6}" 31 | EndProject 32 | Global 33 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 34 | Debug|Any CPU = Debug|Any CPU 35 | Release|Any CPU = Release|Any CPU 36 | EndGlobalSection 37 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 38 | {997632FF-C939-410F-8797-1AD7B8482F21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {997632FF-C939-410F-8797-1AD7B8482F21}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {997632FF-C939-410F-8797-1AD7B8482F21}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {997632FF-C939-410F-8797-1AD7B8482F21}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {61A44935-53EE-45C0-B7FA-A1CDA43BFF71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {61A44935-53EE-45C0-B7FA-A1CDA43BFF71}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {61A44935-53EE-45C0-B7FA-A1CDA43BFF71}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {61A44935-53EE-45C0-B7FA-A1CDA43BFF71}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {0EB97F72-DABA-4E6C-842D-303C3AE91075}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {0EB97F72-DABA-4E6C-842D-303C3AE91075}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {0EB97F72-DABA-4E6C-842D-303C3AE91075}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {0EB97F72-DABA-4E6C-842D-303C3AE91075}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {623680B5-6C19-4159-8C6D-5682FFBB4D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {623680B5-6C19-4159-8C6D-5682FFBB4D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {623680B5-6C19-4159-8C6D-5682FFBB4D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {623680B5-6C19-4159-8C6D-5682FFBB4D5F}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {C5E17F51-0B21-448A-94FF-6090DA09DBB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {C5E17F51-0B21-448A-94FF-6090DA09DBB4}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {C5E17F51-0B21-448A-94FF-6090DA09DBB4}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {C5E17F51-0B21-448A-94FF-6090DA09DBB4}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {F7CC885B-39F3-4B37-984D-31B2D47AD984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {F7CC885B-39F3-4B37-984D-31B2D47AD984}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {F7CC885B-39F3-4B37-984D-31B2D47AD984}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {F7CC885B-39F3-4B37-984D-31B2D47AD984}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {4C2132CF-6FB7-47E6-8275-C1387D7814A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {4C2132CF-6FB7-47E6-8275-C1387D7814A1}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {4C2132CF-6FB7-47E6-8275-C1387D7814A1}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {4C2132CF-6FB7-47E6-8275-C1387D7814A1}.Release|Any CPU.Build.0 = Release|Any CPU 66 | {C38DEE73-5240-4F3F-B9FC-4F622380557F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 67 | {C38DEE73-5240-4F3F-B9FC-4F622380557F}.Debug|Any CPU.Build.0 = Debug|Any CPU 68 | {C38DEE73-5240-4F3F-B9FC-4F622380557F}.Release|Any CPU.ActiveCfg = Release|Any CPU 69 | {C38DEE73-5240-4F3F-B9FC-4F622380557F}.Release|Any CPU.Build.0 = Release|Any CPU 70 | {6CFF5D6A-71DF-4BDF-B6A9-203B78EEF445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 71 | {6CFF5D6A-71DF-4BDF-B6A9-203B78EEF445}.Debug|Any CPU.Build.0 = Debug|Any CPU 72 | {6CFF5D6A-71DF-4BDF-B6A9-203B78EEF445}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {6CFF5D6A-71DF-4BDF-B6A9-203B78EEF445}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {41D4D834-9820-456F-AA68-7BE70F257C62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 75 | {41D4D834-9820-456F-AA68-7BE70F257C62}.Debug|Any CPU.Build.0 = Debug|Any CPU 76 | {41D4D834-9820-456F-AA68-7BE70F257C62}.Release|Any CPU.ActiveCfg = Release|Any CPU 77 | {41D4D834-9820-456F-AA68-7BE70F257C62}.Release|Any CPU.Build.0 = Release|Any CPU 78 | {431412E3-A0AA-4DCE-86BA-5F6716522890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {431412E3-A0AA-4DCE-86BA-5F6716522890}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {431412E3-A0AA-4DCE-86BA-5F6716522890}.Release|Any CPU.ActiveCfg = Release|Any CPU 81 | {431412E3-A0AA-4DCE-86BA-5F6716522890}.Release|Any CPU.Build.0 = Release|Any CPU 82 | {D7FF2B97-9DD4-46C5-BD3D-72F027C6A5F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 83 | {D7FF2B97-9DD4-46C5-BD3D-72F027C6A5F0}.Debug|Any CPU.Build.0 = Debug|Any CPU 84 | {D7FF2B97-9DD4-46C5-BD3D-72F027C6A5F0}.Release|Any CPU.ActiveCfg = Release|Any CPU 85 | {D7FF2B97-9DD4-46C5-BD3D-72F027C6A5F0}.Release|Any CPU.Build.0 = Release|Any CPU 86 | {4DDDE0EF-DDDA-454B-B50A-363BD38E27B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 87 | {4DDDE0EF-DDDA-454B-B50A-363BD38E27B6}.Debug|Any CPU.Build.0 = Debug|Any CPU 88 | {4DDDE0EF-DDDA-454B-B50A-363BD38E27B6}.Release|Any CPU.ActiveCfg = Release|Any CPU 89 | {4DDDE0EF-DDDA-454B-B50A-363BD38E27B6}.Release|Any CPU.Build.0 = Release|Any CPU 90 | EndGlobalSection 91 | GlobalSection(SolutionProperties) = preSolution 92 | HideSolutionNode = FALSE 93 | EndGlobalSection 94 | EndGlobal 95 | --------------------------------------------------------------------------------