├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── conventional-commits.yml ├── .gitignore ├── .gitpod.yml ├── .vsts-ci.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── License.md ├── build └── AssemblyVersion.cs ├── doc ├── .feature-template.md ├── Class Lifecycle Generation.md ├── Compilation References.md ├── Equality Generation.md ├── Immutable Generation.md ├── Injectable Generation.md ├── ReleaseNotes │ └── _ReleaseNotes.md ├── assets │ ├── equality-snippet.png │ └── immutability-snippet.png └── faq.md ├── gitversion.yml ├── readme.md └── src ├── Uno.ClassLifecycle ├── ConstructorMethodAttribute.cs ├── DisposeMethodAttribute.cs ├── FinalizerMethodAttribute.cs └── Uno.ClassLifecycle.csproj ├── Uno.CodeGen.ClassLifecycle ├── Build │ └── Uno.CodeGen.ClassLifecycle.props ├── ClassLifecycleGenerator.cs ├── DisposeImplementationKind.cs ├── DisposePatternImplementationKind.cs ├── LifecycleMethods.cs ├── Properties │ └── launchSettings.json ├── Uno.CodeGen.ClassLifecycle.csproj └── Utils │ ├── EnumerableExtensions.cs │ ├── NamedTypeSymbolExtensions.cs │ ├── StringExtensions.cs │ └── SymbolNames.cs ├── Uno.CodeGen.Tests.ExternalClasses ├── AbstractExternalClass.cs ├── AbstractExternalGenericClass.cs ├── ConcreteExternalClass.cs ├── ConcreteExternalGenericClass.cs ├── MyViewModel.cs ├── SubNamespace │ ├── ConcreteExternalClass.cs │ └── ConcreteExternalGenericClass.cs └── Uno.CodeGen.Tests.ExternalClasses.csproj ├── Uno.CodeGen.Tests.JsonDisabled ├── JsonTestObj.cs └── Uno.CodeGen.Tests.JsonDisabled.csproj ├── Uno.CodeGen.Tests.MinimalDeps ├── JsonTestObj.cs └── Uno.CodeGen.Tests.MinimalDeps.csproj ├── Uno.CodeGen.Tests ├── Given_ClassLifecycle.cs ├── Given_GeneratedEquality.Collections.cs ├── Given_GeneratedEquality.CustomComparers.cs ├── Given_GeneratedEquality.DerivedTypes.cs ├── Given_GeneratedEquality.Enums.cs ├── Given_GeneratedEquality.Indexer.cs ├── Given_GeneratedEquality.KeyEquality.cs ├── Given_GeneratedEquality.Strings.cs ├── Given_GeneratedEquality.cs ├── Given_ImmutableEntity.Fields.cs ├── Given_ImmutableEntity.GenericsAndAbstract.cs ├── Given_ImmutableEntity.Inheritance.cs ├── Given_ImmutableEntity.Newtownsoft.cs ├── Given_ImmutableEntity.NoJson.cs ├── Given_ImmutableEntity.Options.cs ├── Given_ImmutableEntity.SystemTextJson.cs ├── Given_ImmutableEntity.TreatAsImmutable.cs ├── Given_ImmutableEntity.cs ├── Given_Injectable.cs ├── Uno.CodeGen.Tests.csproj └── Uno.CodeGen.Tests.ruleset ├── Uno.CodeGen.sln ├── Uno.CodeGen ├── CompilationReferencesListingGenerator.cs ├── EqualityGenerator.cs ├── Helpers │ ├── NamedTypeSymbolExtensions.cs │ ├── StringExtensions.cs │ └── TypeSymbolExtensions.cs ├── ImmutableGenerator.cs ├── InjectableGenerator.cs ├── Properties │ └── launchSettings.json ├── Uno.CodeGen.csproj └── build │ └── Uno.CodeGen.props ├── Uno.Common.props ├── Uno.Equality ├── CollectionComparerMode.cs ├── DictionaryEqualityComparer.cs ├── EqualityComparerOptionsAttribute.cs ├── EqualityHashAttribute.cs ├── EqualityIgnoreAttribute.cs ├── EqualityKeyAttribute.cs ├── GeneratedEqualityAttribute.cs ├── KeyEqualityMode.cs ├── ReadonlyDictionaryEqualityComparer.cs ├── SortedCollectionEqualityComparer.cs ├── SortedReadonlyCollectionEqualityComparer.cs ├── StringComparerMode.cs ├── Uno.Equality.csproj ├── UnsortedCollectionEqualityComparer.cs └── UnsortedReadonlyCollectionEqualityComparer.cs ├── Uno.Immutables ├── GeneratedImmutableAttribute.cs ├── IImmutableBuilder.cs ├── ImmutableAttribute.cs ├── ImmutableAttributeCopyIgnoreAttribute.cs ├── ImmutableBuilderAttribute.cs ├── ImmutableGenerationOptionsAttribute.cs ├── TreatAsImmutableAttribute.cs └── Uno.Immutables.csproj ├── Uno.Injectable ├── DependencyResolver.cs ├── IInjectable.cs ├── InjectAttribute.cs └── Uno.Injectable.csproj └── crosstargeting_override.props.sample /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = crlf 5 | tab_width = 4 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | 9 | [*.xml] 10 | indent_style = tab 11 | 12 | [*.xaml] 13 | indent_style = tab 14 | 15 | [*.cs] 16 | indent_style = tab 17 | 18 | [*.json] 19 | indent_style = tab 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | ## I'm submitting a... 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Current behavior 17 | 18 | 19 | 20 | ## Expected behavior 21 | 22 | 23 | 24 | ## Minimal reproduction of the problem with instructions 25 | 28 | 29 | 30 | ## Environment 31 | 32 | ``` 33 | Nuget Package: 34 | 35 | Package Version(s): 36 | 37 | Affected platform(s): 38 | - [ ] iOS 39 | - [ ] Android 40 | - [ ] WebAssembly 41 | - [ ] Windows 42 | - [ ] Build tasks 43 | 44 | Visual Studio 45 | - [ ] 2017 (version: ) 46 | - [ ] 2017 Preview (version: ) 47 | - [ ] for Mac (version: ) 48 | 49 | Relevant plugins 50 | - [ ] Resharper (version: ) 51 | ``` 52 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | GitHub Issue (If applicable): # 2 | 3 | 4 | ## PR Type 5 | What kind of change does this PR introduce? 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | ## What is the current behavior? 18 | 19 | 20 | 21 | ## What is the new behavior? 22 | 23 | 24 | 25 | ## PR Checklist 26 | 27 | Please check if your PR fulfills the following requirements: 28 | 29 | - [ ] Tested code with current [supported SDKs](../README.md) 30 | - [ ] Docs have been added/updated which fit [documentation template](https://github.com/nventive/Uno.CodeGen/tree/master/doc/.feature-template.md). (for bug fixes / features) 31 | - [ ] Tests for the changes have been added (for bug fixes / features) (if applicable) 32 | - [ ] Contains **NO** breaking changes 33 | - [ ] Updated the [Release Notes](https://github.com/nventive/Uno.CodeGen/tree/master/doc/ReleaseNotes) 34 | - [ ] Associated with an issue (GitHub or internal) 35 | 36 | 38 | 39 | 40 | ## Other information 41 | 42 | 43 | Internal Issue (If applicable): 44 | -------------------------------------------------------------------------------- /.github/workflows/conventional-commits.yml: -------------------------------------------------------------------------------- 1 | name: Conventional Commits 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | - release/* 8 | 9 | env: 10 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 11 | 12 | jobs: 13 | commitsar: 14 | name: Validate for conventional commits 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v1 19 | - name: Run commitsar 20 | uses: docker://outillage/commitsar:0.11.2 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # Remove everything beginning with a dot 5 | .*/ 6 | !.github/ 7 | 8 | # User-specific files 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Build results 18 | [Dd]ebug[-\w]*/ 19 | [Dd]ebugPublic/ 20 | [Rr]elease[-\w]*/ 21 | [Rr]eleases/ 22 | [Xx]64/ 23 | [Xx]86/ 24 | # [Bb]uild/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | 29 | # Visual Studio 2015 cache/options directory 30 | .vs/ 31 | # Uncomment if you have tasks that create the project's static files in wwwroot 32 | #wwwroot/ 33 | 34 | # MSTest test Results 35 | [Tt]est[Rr]esult*/ 36 | [Bb]uild[Ll]og.* 37 | 38 | # NUNIT 39 | *.VisualState.xml 40 | TestResult.xml 41 | 42 | # Build Results of an ATL Project 43 | [Dd]ebugPS/ 44 | [Rr]eleasePS/ 45 | dlldata.c 46 | 47 | # DNX 48 | project.lock.json 49 | artifacts/ 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.mdb 60 | *.pgc 61 | *.pgd 62 | *.rsp 63 | *.sbr 64 | *.tlb 65 | *.tli 66 | *.tlh 67 | *.tmp 68 | *.tmp_proj 69 | *.log 70 | *.vspscc 71 | *.vssscc 72 | .builds 73 | *.pidb 74 | *.svclog 75 | *.binlog 76 | *.scc 77 | 78 | # Chutzpah Test files 79 | _Chutzpah* 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opendb 86 | *.opensdf 87 | *.sdf 88 | *.cachefile 89 | *.VC.db 90 | 91 | # Visual Studio profiler 92 | *.psess 93 | *.vsp 94 | *.vspx 95 | *.sap 96 | 97 | # TFS 2012 Local Workspace 98 | $tf/ 99 | 100 | # Guidance Automation Toolkit 101 | *.gpState 102 | 103 | # ReSharper is a .NET coding add-in 104 | _ReSharper*/ 105 | *.[Rr]e[Ss]harper 106 | *.DotSettings.user 107 | 108 | # JustCode is a .NET coding add-in 109 | .JustCode 110 | 111 | # DotCover is a Code Coverage Tool 112 | *.dotCover 113 | 114 | # MightyMoose 115 | *.mm.* 116 | AutoTest.Net/ 117 | 118 | # DocProject is a documentation generator add-in 119 | DocProject/buildhelp/ 120 | DocProject/Help/*.HxT 121 | DocProject/Help/*.HxC 122 | DocProject/Help/*.hhc 123 | DocProject/Help/*.hhk 124 | DocProject/Help/*.hhp 125 | DocProject/Help/Html2 126 | DocProject/Help/html 127 | 128 | # Click-Once directory 129 | publish/ 130 | 131 | # Publish Web Output 132 | *.[Pp]ublish.xml 133 | *.azurePubxml 134 | 135 | # TODO: Un-comment the next line if you do not want to checkin 136 | # your web deploy settings because they may include unencrypted 137 | # passwords 138 | #*.pubxml 139 | *.publishproj 140 | 141 | # NuGet Packages 142 | #*.nupkg 143 | # The packages folder can be ignored because of Package Restore 144 | #**/packages/* 145 | # except build/, which is used as an MSBuild target. 146 | #!**/packages/build/ 147 | # Uncomment if necessary however generally it will be regenerated when needed 148 | #!**/packages/repositories.config 149 | # NuGet v3's project.json files produces more ignoreable files 150 | *.nuget.props 151 | *.nuget.targets 152 | 153 | # Microsoft Azure Build Output 154 | csx/ 155 | *.build.csdef 156 | 157 | # Microsoft Azure Emulator 158 | ecf/ 159 | rcf/ 160 | 161 | # Microsoft Azure ApplicationInsights config file 162 | ApplicationInsights.config 163 | 164 | # Windows Store app package directory 165 | AppPackages/ 166 | BundleArtifacts/ 167 | 168 | # Visual Studio cache files 169 | # files ending in .cache can be ignored 170 | *.[Cc]ache 171 | # but keep track of directories ending in .cache 172 | !*.[Cc]ache/ 173 | 174 | # Others 175 | ClientBin/ 176 | [Ss]tyle[Cc]op.* 177 | ~$* 178 | *~ 179 | *.dbmdl 180 | *.dbproj.schemaview 181 | *.pfx 182 | *.publishsettings 183 | node_modules/ 184 | orleans.codegen.cs 185 | 186 | # RIA/Silverlight projects 187 | Generated_Code/ 188 | 189 | # Backup & report files from converting an old project file 190 | # to a newer Visual Studio version. Backup files are not needed, 191 | # because we have git ;-) 192 | _UpgradeReport_Files/ 193 | Backup*/ 194 | UpgradeLog*.XML 195 | UpgradeLog*.htm 196 | 197 | # SQL Server files 198 | *.mdf 199 | *.ldf 200 | 201 | # Business Intelligence projects 202 | *.rdl.data 203 | *.bim.layout 204 | *.bim_*.settings 205 | 206 | # Microsoft Fakes 207 | FakesAssemblies/ 208 | 209 | # GhostDoc plugin setting file 210 | *.GhostDoc.xml 211 | 212 | # Node.js Tools for Visual Studio 213 | .ntvs_analysis.dat 214 | 215 | # Visual Studio 6 build log 216 | *.plg 217 | 218 | # Visual Studio 6 workspace options file 219 | *.opt 220 | 221 | # Paket dependency manager 222 | .paket/paket.exe 223 | 224 | # FAKE - F# Make 225 | .fake/ 226 | 227 | # Xamarin Android 228 | Resource.Designer.cs 229 | *.bak 230 | */nuget_version_override.txt 231 | /src/crosstargeting_override.props 232 | /build/tools/** 233 | !build/tools/packages.config 234 | /build/*.nupkg 235 | /src/Uno.CodeGen.Tests/g 236 | /src/Uno.CodeGen.Tests.ExternalClasses/g 237 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | image: mcr.microsoft.com/dotnet/core/sdk:3.0 2 | 3 | tasks: 4 | # This task is run as part of the pre-build, but also during workspace init. 5 | # Forces the nuget restore path to be part of the restored workspace content, 6 | # so any subsequent build in the workspace will be faster (no nuget restore). 7 | - before: echo "export NUGET_PACKAGES=/workspace/.nuget" >> ~/.profile 8 | command: export NUGET_PACKAGES=/workspace/.nuget 9 | 10 | github: 11 | prebuilds: 12 | # enable for the master/default branch (defaults to true) 13 | master: true 14 | # enable for all branches in this repo (defaults to false) 15 | branches: false 16 | # enable for pull requests coming from this repo (defaults to true) 17 | pullRequests: true 18 | # enable for pull requests coming from forks (defaults to false) 19 | pullRequestsFromForks: true 20 | # add a check to pull requests (defaults to true) 21 | addCheck: true 22 | # add a "Review in Gitpod" button as a comment to pull requests (defaults to false) 23 | addComment: true 24 | # add a "Review in Gitpod" button to the pull request's description (defaults to false) 25 | addBadge: false 26 | # add a label once the prebuild is ready to pull requests (defaults to false) 27 | addLabel: false 28 | -------------------------------------------------------------------------------- /.vsts-ci.yml: -------------------------------------------------------------------------------- 1 | pool: 2 | vmImage: 'windows-2022' 3 | 4 | trigger: 5 | branches: 6 | include: 7 | - master 8 | - beta 9 | - release/beta/* 10 | - stable 11 | - release/stable/* 12 | 13 | pr: 14 | branches: 15 | include: 16 | - master 17 | - beta 18 | - release/beta/* 19 | - stable 20 | - release/stable/* 21 | 22 | steps: 23 | - checkout: self 24 | clean: 'true' 25 | 26 | - task: gitversion/setup@0 27 | inputs: 28 | versionSpec: '5.6.8' 29 | 30 | - task: gitversion/execute@0 31 | inputs: 32 | useConfigFile: true 33 | configFilePath: gitversion.yml 34 | displayName: Use GitVersion 35 | 36 | - task: MSBuild@1 37 | inputs: 38 | solution: src/Uno.CodeGen.sln 39 | msbuildArchitecture: x86 40 | msbuildArguments: /r /p:Configuration=Release "/p:PackageOutputPath=$(build.artifactstagingdirectory)\vslatest" "/p:PackageVersion=%GITVERSION_FullSemVer%" "/p:InformationalVersion=%GITVERSION_InformationalVersion%" /detailedsummary 41 | clean: false 42 | maximumCpuCount: true 43 | restoreNugetPackages: false 44 | logProjectEvents: false 45 | createLogFile: false 46 | 47 | - task: VisualStudioTestPlatformInstaller@1 48 | 49 | - task: VSTest@2 50 | inputs: 51 | testAssemblyVer2: | 52 | **\*test*.dll 53 | !**\obj\** 54 | vsTestVersion: toolsInstaller 55 | testSelector: testAssemblies 56 | 57 | - task: PublishBuildArtifacts@1 58 | inputs: 59 | ArtifactName: $(Build.DefinitionName) 60 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community. For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct). -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | There are lots of ways to contribute to the Uno CodeGen Tasks and we appreciate the help from the community. You can provide feedback, report bugs, give suggestions, contribute code, and participate in the platform discussions. 4 | 5 | ## Code of conduct 6 | 7 | To better foster an open, innovative and inclusive community please refer to our [Code of Conduct](CODE_OF_CONDUCT.md) when contributing. 8 | 9 | ### Report a bug 10 | 11 | If you think you've found a bug, please log a new issue in the [Uno CodeGen GitHub issue tracker](https://github.com/nventive/Uno.CodeGen/issues). When filing issues, please use our [bug filing template](.github/ISSUE_TEMPLATE.md). 12 | The best way to get your bug fixed is to be as detailed as you can be about the problem. 13 | Providing a minimal project with steps to reproduce the problem is ideal. 14 | Here are questions you can answer before you file a bug to make sure you're not missing any important information. 15 | 16 | 1. Did you read the [documentation](https://github.com/nventive/Uno.CodeGen/tree/master/doc)? 17 | 2. Did you include the snippet of broken code in the issue? 18 | 3. What are the *EXACT* steps to reproduce this problem? 19 | 4. What specific version or build are you using? 20 | 5. What operating system are you using? 21 | 22 | GitHub supports [markdown](https://help.github.com/articles/github-flavored-markdown/), so when filing bugs make sure you check the formatting before clicking submit. 23 | 24 | ### Make a suggestion 25 | 26 | If you have an idea for a new feature or enhancement let us know by filing an [issue](https://github.com/nventive/Uno.CodeGen/issues). To help us understand and prioritize your idea please provide as much detail about your scenario and why the feature or enhancement would be useful. 27 | 28 | ### Ask questions 29 | 30 | If you have a question be sure to first checkout our [documentation](https://github.com/nventive/Uno.CodeGen/tree/master/doc). But if you are still stuck, you'll have a better chance of getting help on [StackOverflow](https://stackoverflow.com/questions/tagged/uno-platform) and we'll do our best to answer it. Questions asked there should be tagged with `uno-platform`. 31 | 32 | For a more direct conversation, [our gitter is also a good place to visit](https://gitter.im/uno-platform/Lobby). 33 | 34 | ## Contributing code and content 35 | 36 | The Uno Platform is an open source project and we welcome code and content contributions from the community. 37 | 38 | **Identifying the scale** 39 | 40 | If you would like to contribute to one of our repositories, first identify the scale of what you would like to contribute. If it is small (grammar/spelling or a bug fix) feel free to start working on a fix. 41 | 42 | If you are submitting a feature or substantial code contribution, please discuss it with the team. You might also read these two blogs posts on contributing code: [Open Source Contribution Etiquette](http://tirania.org/blog/archive/2010/Dec-31.html) by Miguel de Icaza and [Don't "Push" Your Pull Requests](https://www.igvita.com/2011/12/19/dont-push-your-pull-requests/) by Ilya Grigorik. Note that all code submissions will be rigorously reviewed and tested by the Uno Platform team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source. 43 | 44 | **Obtaining the source code** 45 | 46 | If you are an outside contributer, please fork the Uno CodeGen repository you would like to contribute to your account. See the GitHub documentation for [forking a repo](https://help.github.com/articles/fork-a-repo/) if you have any questions about this. 47 | 48 | **Submitting a pull request** 49 | 50 | If you don't know what a pull request is read this article: https://help.github.com/articles/using-pull-requests. Make sure the respository can build and all tests pass, as well as follow the current coding guidelines. 51 | 52 | Pull requests should all be done to the **master** branch. 53 | 54 | **Commit/Pull Request Format** 55 | 56 | ``` 57 | Summary of the changes (Less than 80 chars) 58 | - Detail 1 59 | - Detail 2 60 | 61 | Addresses #bugnumber (in this specific format) 62 | ``` 63 | 64 | **Tests** 65 | 66 | - Tests need to be provided for every bug/feature that is completed. 67 | - Tests only need to be present for issues that need to be verified by QA (e.g. not tasks) 68 | - If there is a scenario that is far too hard to test there does not need to be a test for it. 69 | - "Too hard" is determined by the team as a whole. 70 | -------------------------------------------------------------------------------- /build/AssemblyVersion.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | [assembly: System.Reflection.AssemblyVersion("1.17.0.0")] 12 | [assembly: System.Reflection.AssemblyFileVersion("1.17.0.0")] 13 | [assembly: System.Reflection.AssemblyInformationalVersion("1.17.0-dev.0+Branch.master.Sha.0c2c9de2cd573d2042ce42110540c0ef84bc5968")] 14 | [assembly: System.Reflection.AssemblyProduct("Uno.Core")] 15 | [assembly: System.Reflection.AssemblyCompany("nventive")] 16 | [assembly: System.Reflection.AssemblyCopyright("Copyright (C) nVentive 2011-2018")] 17 | 18 | 19 | -------------------------------------------------------------------------------- /doc/.feature-template.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 3 | author: GitHub_UserName 4 | description: describe your feature implementation 5 | keywords: uno platform, your feature 6 | dev_langs: 7 | - csharp 8 | --- 9 | 10 | 11 | 12 | 13 | 14 | # Title 15 | 16 | The [Feature name] ... 17 | 18 | 28 | 29 | ## Syntax 30 | 31 | ```csharp 32 | 33 | ``` 34 | 35 | ```xaml 36 | 37 | ``` 38 | 39 | ## Sample Output 40 | 41 | 42 | 43 | ## Sample Code 44 | 45 | 46 | 47 | ## Requirements 48 | 49 | | Device family | Universal, MinVersion or higher | 50 | | -- | -- | 51 | | iOS | | 52 | | Android | | 53 | | WebAssembly | | 54 | 55 | ## Limitations 56 | 57 | 58 | 59 | ## API Source Code 60 | 61 | - [control/helper name source code](source-code-link) 62 | 63 | ## Related Topics 64 | 65 | 66 | 67 | - [Topic 1](link) 68 | - [Topic 2](link) 69 | -------------------------------------------------------------------------------- /doc/Class Lifecycle Generation.md: -------------------------------------------------------------------------------- 1 | # Class Lifecyle Generation 2 | 3 | ## Quick Start 4 | 5 | 1. Add a reference to the `Uno.CodeGen.ClassLifecycle` _Nuget_ package in your project. 6 | [![NuGet](https://img.shields.io/nuget/v/Uno.CodeGen.svg)](https://www.nuget.org/packages/Uno.CodeGen/) 7 | 1. Create a new class and add methods one of the following attributes 8 | - `[ConstructorMethod]` 9 | - `[DisposeMethod]` 10 | - `[FinalizerMethod]` 11 | ``` csharp 12 | public partial class MyClass 13 | { 14 | [ConstructorMethod] 15 | private void MyConstructor() 16 | { 17 | } 18 | 19 | [DisposeMethod] 20 | private void MyDispose() 21 | { 22 | } 23 | 24 | [FinalizerMethod] 25 | private void MyFinalizer() 26 | { 27 | } 28 | } 29 | ``` 30 | 31 | 1. Compile ([the generation process occurs at compile time](https://github.com/nventive/Uno.SourceGeneration/issues/9)). 32 | 1. It will generate the following public methods for you: 33 | ``` csharp 34 | partial class MyClass : IDisposable 35 | { 36 | // If none defined on your class, a default constructor which invokes the Initialize() 37 | public MyClass() 38 | { 39 | Initialize(); 40 | } 41 | 42 | // The initialize method which must be invoked in each constructor 43 | private void Initialize() 44 | { 45 | MyConstructor(); 46 | } 47 | 48 | // Disposable pattern implementation 49 | protected virtual void Dispose(bool isDisposing) 50 | { 51 | if (isDisposing) 52 | { 53 | this.MyDispose(); 54 | } 55 | } 56 | 57 | // IDisposable implementation 58 | public void Dispose() 59 | { 60 | Dispose(true); 61 | } 62 | 63 | // Class finalizer 64 | ~MyClass() 65 | { 66 | Dispose(false); 67 | this.MyFinalizer(); 68 | } 69 | } 70 | ``` 71 | 72 | ## Constructor Rules 73 | 74 | If you have any method which is marked with the `[ConstructorMethod]` attribute, an `Initialize` 75 | method will be generated. 76 | 77 | 1. *All* constructors of the class *must* invoke the `Initialize` method (either directly 78 | in its body, or by invoking an other constructor. 79 | 1. Parameters: 80 | You can have some parameters on your constructor methods. They will be aggregated 81 | as parameters of the `Initialize()` method. 82 | - To be consistent between builds, they are sorted using the following rules: 83 | 1. Non optional parameters 84 | 1. Alphabetically 85 | - If a parameter is optional, its default value will also be copied. 86 | - If two methods are defining a parameter with the same name: 87 | - If they have the same type, they will be merged, otherwise an error will be generated. 88 | - If they are booth optional, and the default value is the same, they will stay optional 89 | on the `Initialize`. If default value are different, an error will be generated. 90 | If any is non optional, it will be required. 91 | 1. If you don't have any parameter-less constructor defined in your class, and the `Initialize` 92 | doesn't have any non optional parameter, then a parameter-less constructor will be 93 | generated. It will invoke the `Initialize` for you, so you only have to invoked 94 | it in your own constructors: 95 | ```csharp 96 | public MyClass(string aParameter) 97 | *: this()* 98 | { 99 | ../.. 100 | } 101 | ``` 102 | 1. The return type of the method marked with `[ConstructorMethod]` must be `void` 103 | 104 | ## Dispose Rules 105 | 106 | If you have any method marked with the `[DisposeMethod]` attribute, the generation 107 | will make your class implement `IDisposable`, and ensure to invoke your methods when the 108 | `IDisposable.Dispose` method is invoked. 109 | 110 | 1. Your methods must not have any parameter. 111 | 1. The return type of the method marked with `[DisposeMethod]` must be `void` 112 | 1. Your class must not implement `IDisposable` itself. If you want to add stuff 113 | to the dispose process, add another method marked with `[DisposeMethod]`. 114 | 1. If your class inherits from a class which already implements IDisposable: 115 | 1. If the base class implements the 116 | [dispose pattern](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern), 117 | the generated code will override the `Dispose(bool isDisposing)` method. 118 | 1. If the base class is `Uno.Core.IExtensibleDisposable`, it will register itself 119 | as an extention. 120 | 1. If the `Dispose()` method is virtual, it will override it. 121 | 1. As the override in not possible, an error will be generated. 122 | 123 | ## Finalizer Rules 124 | 125 | If you have any method which is marked with the `[FinalizerMethod]` attribute, the generation 126 | will generate the class finalizer (`~MyClass`), and ensure to invoke your methods when invoked. 127 | 128 | 1. Your methods must not have any parameter. 129 | 1. The return type of the method marked with `[FinalizerMethod]` must be `void` 130 | 1. Your class must not define the finalizer itself. If you want to add stuff 131 | to the finalize process, add another method marked with `[FinalizerMethod]`. 132 | -------------------------------------------------------------------------------- /doc/Compilation References.md: -------------------------------------------------------------------------------- 1 | # Compilation References Listing Generator 2 | 3 | This generator will generate a list of references used to compile your project. 4 | 5 | For the output, check for `CompilationReferencesListingGenerator.g.cs` in `obj\\\g\CompilationReferencesListingGenerator`. -------------------------------------------------------------------------------- /doc/Injectable Generation.md: -------------------------------------------------------------------------------- 1 | # Injectable Generation 2 | 3 | An injectable (`IInjectable`) is a type that will populate its `[Inject]` attributed members (properties and fields) when `IInjectable.Inject(DependencyResolver resolver)` is called. This is typically used for dependency injection. 4 | 5 | `InjectableGeneration` will generate a partial class that implements `IInjectable` for every class that contains at least one `[Inject]` attributed member. The generated `IInjectable.Inject` implementation will automatically resolve dependencies and populate members. 6 | 7 | You should never have to implement `IInjectable` yourself, but you must manually call `IInjectable.Inject(DependencyResolver resolver)` with the appropritate dependency resolver (e.g., `ServiceLocator`). 8 | 9 | ## Quick Start 10 | 11 | 1. Add a reference to the `Uno.CodeGen` _NuGet_ package in your project. 12 | [![NuGet](https://img.shields.io/nuget/v/Uno.CodeGen.svg)](https://www.nuget.org/packages/Uno.CodeGen/) 13 | 1. Add the `[Inject]` attribute to members (fields and properties) of a class that should be injected. Make sure the class is partial. 14 | ```csharp 15 | public partial class MyViewModel 16 | { 17 | [Inject] IMyService MyService; 18 | [Inject("name")] IMyService MyNamedService; 19 | [Inject] Func MyLazyService; 20 | } 21 | ``` 22 | 1. Compile (this is important to generate the partial portion of the class). 23 | 1. A partial class that implements `IInjectable` will be generated: 24 | ```csharp 25 | partial class MyViewModel : IInjectable 26 | { 27 | void IInjectable.Inject(DependencyResolver resolver) 28 | { 29 | MyService = (IMyService)resolver(type: typeof(IMyService), name: null); 30 | MyNamedService = (IMyService)resolver(type: typeof(IMyService), name: "name"); 31 | MyLazyService = () => (IMyService)resolver(type: typeof(IMyService), name: null); 32 | } 33 | } 34 | ``` 35 | 1. Inject a dependency resolver to initialize `[Inject]` attributed members: 36 | ```csharp 37 | if (myViewModel is IInjectable injectable) 38 | { 39 | injectable.Inject(resolver: (type, name) => serviceLocator.GetInstance(type, name)); 40 | } 41 | ``` 42 | 1. All `[Inject]` attributed members should now be populated with the appropriate dependencies. -------------------------------------------------------------------------------- /doc/ReleaseNotes/_ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | ## Next version 4 | 5 | ### Features 6 | 7 | ### Breaking changes 8 | 9 | ### Bug fixes 10 | 11 | ## Release 1.32.0 12 | 13 | * No major changes. 14 | 15 | ## Release 1.31.0 16 | 17 | ### Features 18 | 19 | * Equality: You can now use `enum` as member types for `[EqualityHash]` and `[EqualityKey]` 20 | * Immutability: readonly fields are now allowed when they are of immutable types. 21 | 22 | ### Bug fixes 23 | * Equality: Using an indexer won't break the code generation anymore. 24 | 25 | ## Release 1.30.0 26 | 27 | * No major changes. 28 | 29 | ## 1.22.0 (May 17th 2018) 30 | 31 | * Added support for System.Guid as a supported immutable type. 32 | -------------------------------------------------------------------------------- /doc/assets/equality-snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoplatform/Uno.CodeGen/fa24add31c90bb6b57a5163bf02bdc48c87828d1/doc/assets/equality-snippet.png -------------------------------------------------------------------------------- /doc/assets/immutability-snippet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoplatform/Uno.CodeGen/fa24add31c90bb6b57a5163bf02bdc48c87828d1/doc/assets/immutability-snippet.png -------------------------------------------------------------------------------- /doc/faq.md: -------------------------------------------------------------------------------- 1 | # Uno.CodeGen FAQ 2 | 3 | ## How it works? 4 | 5 | Generators are based on the [Uno.SourceGeneration](https://github.com/nventive/Uno.SourceGeneration) project. 6 | 7 | At compile time, they analyze the _Roslyn_ compilation and use it to generate relevant 8 | code. Generated code are placed in the `\obj\\\g\` 9 | folder­ and they are dynamically added to the project compilation. 10 | 11 | ## Is there a way to commit generated code with my project in source control? 12 | 13 | You can set the `UnoSourceGeneratorOutputPath` in your `csproj` file to the desired location 14 | (relative to your project folder). 15 | 16 | If you are using _Sdk_ projects - projects were all `.cs` files are automatically compiled 17 | in your project, the generated files will be part of your project. 18 | 19 | Example: 20 | 21 | ``` xml 22 | GeneratedFiles 23 | ``` 24 | 25 | ## Intellisense is broken for generated code. Is there a way to fix it? 26 | 27 | It should work fine for _Sdk_ projects (new project format that comes with _dot net core_), 28 | but for classical probjects (WPF, Xamarin, UWP, etc...) it seems you need to force VisualStudio 29 | to reset its cache. A quick way to do that is to toggle the _Show All files_ in the _Solution Explorer_. 30 | -------------------------------------------------------------------------------- /gitversion.yml: -------------------------------------------------------------------------------- 1 | assembly-versioning-scheme: MajorMinorPatch 2 | mode: Mainline 3 | 4 | branches: 5 | master: 6 | mode: ContinuousDeployment 7 | regex: master 8 | tag: dev 9 | increment: Minor 10 | is-source-branch-for: ['beta', 'stable'] 11 | 12 | pull-request: 13 | regex: ^(pull|pull\-requests|pr)[/-] 14 | mode: ContinuousDeployment 15 | tag: 'PullRequest' 16 | tag-number-pattern: '[/-](?\d+)[-/]' 17 | increment: Inherit 18 | 19 | beta: 20 | mode: ContinuousDeployment 21 | regex: ^release/beta/.* 22 | tag: beta 23 | increment: none 24 | source-branches: ['master'] 25 | 26 | stable: 27 | regex: ^release/stable/.* 28 | tag: '' 29 | increment: Patch 30 | source-branches: ['master','beta'] 31 | is-mainline: true 32 | 33 | dev: 34 | mode: ContinuousDeployment 35 | regex: ^dev/.*?/(.*?) 36 | tag: dev.{BranchName} 37 | source-branches: ['master', 'release', 'projects', 'feature'] 38 | increment: none 39 | 40 | projects: 41 | tag: proj-{BranchName} 42 | regex: ^projects/(.*?) 43 | source-branches: ['master'] 44 | increment: none 45 | 46 | feature: 47 | tag: feature.{BranchName} 48 | regex: ^feature/(.*?) 49 | source-branches: ['master'] 50 | increment: none 51 | 52 | ignore: 53 | sha: [] 54 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Uno CodeGen 2 | 3 | `Uno.CodeGen` is a set of tools to generate C# code in msbuild based projects. 4 | 5 | ## Generate **Equality Members** for your _C#_ classes 6 | 7 | ![Equality Members generation snippet](doc/assets/equality-snippet.png) 8 | 9 | Features: 10 | 11 | * Amazingly fast: absolutely **zero reflection at runtime** 12 | * Generates both `.Equals()` and `.GetHashCode()` overrrides 13 | * Generates equality (`==` and `!=`) operators 14 | * Implements `IEquatable` 15 | * Works with derived classes 16 | * **Custom comparers** supported 17 | * Works with collection members (both same order and _unsorted_ equality) 18 | * Works with dictionary members (both same order and _unsorted_ equality) 19 | * Optional case insentive comparisons for strings 20 | * Optional support for _KeyEquality_ (see doc for more details) 21 | * Debuggable: You can put a breakpoint directly in the generated code 22 | * Highly configureable: Generated code provides a lot of useful tips (stripped in previous snippet) 23 | * [Documentation here](doc/Equality%20Generation.md) for Equality Members Generator 24 | 25 | ## Create **truly Immutable Entities** in _C#_ 26 | 27 | ![Equality Members generation snippet](doc/assets/immutability-snippet.png) 28 | 29 | Features: 30 | 31 | * Automatic _Null object pattern_ generation 32 | * Automatic generation of `.Builder` nested class 33 | * Fluent `.With()` generation of every members of your class 34 | * Amazingly fast: absolutely **zero reflection at runtime** 35 | * Works with generics & derived classes (even if they are from external assembly) 36 | * Optional support (_on_ by default) for `[GeneratedEquality]` 37 | * Transparent support for _Newtonsoft's JSON.NET_ (activated when detected, can be turned off) 38 | * Transparent support for _System.Text.Json_ (activated when detected, can be turned off) 39 | * Debuggable: You can put a breakpoint directly in the generated code 40 | * Validation to avoid mutable code in your class 41 | * Highly configureable: Generated code provides a lot of useful tips (stripped in previous snippet) 42 | * [Documentation here](doc/Immutable%20Generation.md) for Immutable Entities Generator 43 | 44 | ## Available Generators 45 | 46 | | Generator | Triggering Attributes | Usage | | 47 | | --------- | -------------------- | ----- | -- | 48 | | `ClassLifecycleGenerator` | `[ConstructorMethod]` `[DisposeMethod]` `[FinalizerMethod]` | Generate code to extend the lifecyle of a class. | [Documentation](doc/Class%20Lifecycle%20Generation.md) | 49 | | `CompilationReferencesListingGenerator` | _none_ | Generate a file without _useful_ code, containing only comments detailing references used to compile the project. | [Documentation](doc/Compilation%20References.md) | 50 | | `EqualityGenerator` | `[GenerateEquality]` | Generate code for efficient `.Equals()` members generation. | [Documentation](doc/Equality%20Generation.md) | 51 | | `ImmutableGenerator` | `[GenerateImmutable]` | Generate code to build truly immutable entities. | [Documentation](doc/Immutable%20Generation.md) | 52 | | `InjectableGenerator` | `[Inject]` | Generate code to resolve and inject dependencies. | [Documentation](doc/Injectable%20Generation.md) | 53 | 54 | ## Nuget 55 | 56 | [![NuGet](https://buildstats.info/nuget/Uno.CodeGen?includePreReleases=true)](https://www.nuget.org/packages/Uno.CodeGen/) 57 | 58 | ## FAQ 59 | [Read our FAQ here](doc/faq.md) 60 | 61 | # Have questions? Feature requests? Issues? 62 | 63 | Make sure to visit our [FAQ](doc/faq.md), [StackOverflow](https://stackoverflow.com/questions/tagged/uno-platform), [create an issue](https://github.com/nventive/Uno.CodeGen/issues) or [visit our gitter](https://gitter.im/uno-platform/Lobby). 64 | 65 | # Contributing 66 | 67 | Read our [contributing guide](CONTRIBUTING.md) to learn about our development process and how to propose bug fixes and improvements. 68 | -------------------------------------------------------------------------------- /src/Uno.ClassLifecycle/ConstructorMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Uno 22 | { 23 | /// 24 | /// Marks a method as part of the construction of the object 25 | /// 26 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 27 | public sealed class ConstructorMethodAttribute : Attribute 28 | { 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Uno.ClassLifecycle/DisposeMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | 20 | namespace Uno 21 | { 22 | /// 23 | /// Marks a method as part of the disposale of the object 24 | /// 25 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 26 | public sealed class DisposeMethodAttribute : Attribute 27 | { 28 | } 29 | } -------------------------------------------------------------------------------- /src/Uno.ClassLifecycle/FinalizerMethodAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | 20 | namespace Uno 21 | { 22 | /// 23 | /// Marks a method as part of the construction of the object 24 | /// 25 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] 26 | public sealed class FinalizerMethodAttribute : Attribute 27 | { 28 | } 29 | } -------------------------------------------------------------------------------- /src/Uno.ClassLifecycle/Uno.ClassLifecycle.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netstandard1.3;netstandard2.0 5 | Object life cycle declaration 6 | true 7 | True 8 | 9 | full 10 | True 11 | nventive 12 | nventive 13 | This package provides attributes for object's life cycle source code generation. 14 | This package is part of the Uno.CodeGen to generate object life cycle methods in your project. 15 | Uno 16 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 17 | Copyright (C) 2015-2018 nventive inc. - all rights reserved 18 | https://github.com/nventive/Uno.CodeGen 19 | https://github.com/nventive/Uno.CodeGen 20 | https://nv-assets.azurewebsites.net/logos/uno.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Build/Uno.CodeGen.ClassLifecycle.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/DisposeImplementationKind.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | 20 | namespace Uno.CodeGen.ClassLifecycle 21 | { 22 | internal enum DisposeImplementationKind 23 | { 24 | /// 25 | /// Simple implementation of IDisposable on the class 26 | /// 27 | Dispose, 28 | 29 | /// 30 | /// Simple implementation of IDisposable on the base base 31 | /// 32 | DisposeOnBase, 33 | 34 | /// 35 | /// VIRTUAL simple implementation of IDisposable on the base base 36 | /// 37 | OverridableDisposeOnBase, 38 | 39 | /// 40 | /// Type does not implement IDisposable 41 | /// 42 | None, 43 | } 44 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/DisposePatternImplementationKind.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | 20 | namespace Uno.CodeGen.ClassLifecycle 21 | { 22 | internal enum DisposePatternImplementationKind 23 | { 24 | /// 25 | /// Dispose pattern on the class 26 | /// 27 | DisposePattern, 28 | 29 | /// 30 | /// Dispose pattern on the base class 31 | /// 32 | DisposePatternOnBase, 33 | 34 | /// 35 | /// Dispose pattern on the base class, but SEALED 36 | /// 37 | SealedDisposePatternOnBase, 38 | 39 | /// 40 | /// Dispose pattern on the base class, but NOT OVERRIBALE 41 | /// 42 | NonOverridableDisposePatternOnBase, 43 | 44 | /// 45 | /// Type does not implement Disposable pattern 46 | /// 47 | None, 48 | } 49 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/LifecycleMethods.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using Microsoft.CodeAnalysis; 21 | 22 | namespace Uno.CodeGen.ClassLifecycle 23 | { 24 | internal class LifecycleMethods 25 | { 26 | public INamedTypeSymbol Owner { get; } 27 | public IEnumerable Bases { get; set; } 28 | 29 | public ICollection AllMethods { get; } 30 | public ICollection Constructors { get; } 31 | public ICollection Disposes { get; } 32 | public ICollection Finalizers { get; } 33 | public bool HasLifecycleMethods { get; } 34 | 35 | public LifecycleMethods( 36 | INamedTypeSymbol owner, 37 | ICollection allMethods, 38 | ICollection constructors, 39 | ICollection disposes, 40 | ICollection finalizers) 41 | { 42 | Owner = owner; 43 | AllMethods = allMethods; 44 | Constructors = constructors; 45 | Disposes = disposes; 46 | Finalizers = finalizers; 47 | 48 | HasLifecycleMethods = constructors.Count > 0 || disposes.Count > 0 || finalizers.Count > 0; 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Uno.CodeGen.ClassLifecycle": { 4 | "commandName": "Executable", 5 | "executablePath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\MSBuild\\15.0\\Bin\\MSBuild.exe", 6 | "commandLineArgs": "..\\Uno.CodeGen.Tests\\Uno.CodeGen.Tests.csproj /p:Configuration=Debug" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Uno.CodeGen.ClassLifecycle.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;netstandard2.0 5 | true 6 | Generator of class lifecycle 7 | true 8 | True 9 | 10 | full 11 | True 12 | nventive 13 | nventive 14 | This package provides a generator which generates the class life cycle method using the attributes from Uno.ClassLifecycle. 15 | This package is part of the Uno.CodeGen to generate classes lifecycle methods in your project. 16 | Uno 17 | Copyright (C) 2015-2018 nventive inc. - all rights reserved 18 | https://github.com/nventive/Uno.CodeGen 19 | https://github.com/nventive/Uno.CodeGen 20 | https://nv-assets.azurewebsites.net/logos/uno.png 21 | RS1024;NU5118;NU5128 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | all 36 | runtime; build; native; contentfiles; analyzers 37 | 38 | 39 | NU1701;RS1024 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | true 51 | build 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Utils/EnumerableExtensions.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | 21 | namespace Uno.CodeGen.ClassLifecycle.Utils 22 | { 23 | internal static class EnumerableExtensions 24 | { 25 | public static bool None(this IEnumerable source) => !source.Any(); 26 | 27 | public static bool None(this IEnumerable source, Func predicate) => !source.Any(predicate); 28 | } 29 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Utils/NamedTypeSymbolExtensions.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using Microsoft.CodeAnalysis; 21 | 22 | namespace Uno.CodeGen.ClassLifecycle.Utils 23 | { 24 | internal static class NamedTypeSymbolExtensions 25 | { 26 | public static string SimpleLocationText(this ISymbol symbol) 27 | { 28 | var location = symbol.Locations.First(); // SimpleLocation does not take care of partial stuff 29 | return $"'{symbol.Name}' on line {location.GetLineSpan().StartLinePosition.Line} of file '{location.SourceTree.FilePath}'"; 30 | } 31 | 32 | public static string GetInvocationText(this IMethodSymbol method, string target = "this", params string[] parameters) 33 | { 34 | var explicitInterface = method.ExplicitInterfaceImplementations.FirstOrDefault(); 35 | return explicitInterface == null 36 | ? $"{target}.{method.Name}({parameters.JoinBy(", ")});" 37 | : $"(({explicitInterface.ContainingSymbol}){target}).{explicitInterface.Name}({parameters.JoinBy(", ")});"; 38 | } 39 | 40 | public static string GetInvocationText(this IMethodSymbol method, IEnumerable parameters) 41 | => method.GetInvocationText(parameters: parameters.Select(p => p.Name).ToArray()); 42 | 43 | public static string GlobalTypeDefinitionText(this ITypeSymbol type) 44 | { 45 | if (type.IsNullable(out var nullable)) 46 | { 47 | return $"{nullable.GlobalTypeDefinitionText()}?"; 48 | } 49 | 50 | switch (type.SpecialType) 51 | { 52 | case SpecialType.System_Boolean: 53 | case SpecialType.System_Byte: 54 | case SpecialType.System_Char: 55 | case SpecialType.System_Decimal: 56 | case SpecialType.System_Double: 57 | case SpecialType.System_Int16: 58 | case SpecialType.System_Int32: 59 | case SpecialType.System_Int64: 60 | case SpecialType.System_Object: 61 | case SpecialType.System_SByte: 62 | case SpecialType.System_String: 63 | case SpecialType.System_UInt16: 64 | case SpecialType.System_UInt32: 65 | case SpecialType.System_UInt64: 66 | case SpecialType.System_Void: 67 | return type.ToString(); 68 | 69 | default: 70 | return $"global::{type}"; 71 | } 72 | } 73 | 74 | public static IEnumerable GetNamedTypes(this INamespaceOrTypeSymbol sym) 75 | { 76 | if (sym is INamedTypeSymbol type) 77 | { 78 | yield return type; 79 | } 80 | 81 | foreach (var child in sym.GetMembers().OfType().SelectMany(GetNamedTypes)) 82 | { 83 | yield return child; 84 | } 85 | } 86 | 87 | public static bool HasAttribute(this IMethodSymbol type, INamedTypeSymbol attribute) 88 | => type.FindAttribute(attribute) != null; 89 | 90 | public static AttributeData FindAttribute(this INamedTypeSymbol type, INamedTypeSymbol attributeType) 91 | => type.GetAttributes().FirstOrDefault(attribute => Equals(attribute.AttributeClass, attributeType)); 92 | 93 | public static SymbolNames GetSymbolNames(this INamedTypeSymbol typeSymbol) 94 | { 95 | var namespaceParts = typeSymbol.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat).Split('.'); 96 | var parentParts = typeSymbol.GetContainingTypes().Reverse().Select(parent => new[] { parent.Name }.Concat(parent.GetTypeArgumentNames()).JoinBy("_")); 97 | var fullNameSpace = namespaceParts.Concat(parentParts).ToArray(); 98 | 99 | var symbolName = typeSymbol.Name; 100 | if (typeSymbol.TypeArguments.Length == 0) // not a generic type 101 | { 102 | return new SymbolNames(symbolName, "", symbolName, symbolName, symbolName, symbolName, $"{fullNameSpace.JoinBy("/")}/{symbolName}"); 103 | } 104 | 105 | var argumentNames = typeSymbol.GetTypeArgumentNames(); 106 | var genericArguments = string.Join(", ", argumentNames); 107 | 108 | // symbolNameWithGenerics: MyType 109 | var symbolNameWithGenerics = $"{symbolName}<{genericArguments}>"; 110 | 111 | // symbolNameWithGenerics: MyType<T1, T2> 112 | var symbolForXml = $"{symbolName}<{genericArguments}>"; 113 | 114 | // symbolNameDefinition: MyType<,> 115 | var symbolNameDefinition = $"{symbolName}<{string.Join(",", typeSymbol.TypeArguments.Select(ta => ""))}>"; 116 | 117 | // symbolNameWithGenerics: MyType_T1_T2 118 | var symbolFilename = $"{symbolName}_{string.Join("_", argumentNames)}"; 119 | 120 | // filePath: MyNamespace/MyParentClass_T/MyType_T1_T2 121 | var filePath = $"{fullNameSpace.JoinBy("/")}/{symbolFilename}"; 122 | 123 | return new SymbolNames(symbolName, $"<{genericArguments}>", symbolNameWithGenerics, symbolForXml, symbolNameDefinition, symbolFilename, filePath); 124 | } 125 | 126 | public static string[] GetTypeArgumentNames(this ITypeSymbol typeSymbol) 127 | { 128 | return (typeSymbol as INamedTypeSymbol)?.TypeArguments.Select(ta => ta.MetadataName).ToArray() ?? new string[0]; 129 | } 130 | 131 | public static string GetAvailableTypeArgument(this INamedTypeSymbol type, params string[] possibilities) 132 | { 133 | var alreadyUsed = type.GetTypeArgumentNames(); 134 | 135 | var value = possibilities.FirstOrDefault(p => !alreadyUsed.Contains(p)); 136 | if (value != null) 137 | { 138 | return value; 139 | } 140 | 141 | var fallback = possibilities.Last(); 142 | for (var i = 0; ; i++) 143 | { 144 | value = fallback + i; 145 | if (!alreadyUsed.Contains(value)) 146 | { 147 | return value; 148 | } 149 | } 150 | } 151 | 152 | public static (DisposePatternImplementationKind, IMethodSymbol) GetDisposablePatternImplementation(this INamedTypeSymbol sourceType) 153 | { 154 | var type = sourceType; 155 | 156 | while (type != null) 157 | { 158 | var disposePattern = type 159 | .GetMembers("Dispose") 160 | .OfType() 161 | .FirstOrDefault(method => method.Parameters.Length == 1 && method.Parameters.First().Type.SpecialType == SpecialType.System_Boolean); 162 | 163 | if (disposePattern == null) 164 | { 165 | } 166 | else if (Equals(type, sourceType)) 167 | { 168 | return (DisposePatternImplementationKind.DisposePattern, disposePattern); 169 | } 170 | else if (disposePattern.IsVirtual || (disposePattern.IsOverride && !disposePattern.IsSealed)) 171 | { 172 | return (DisposePatternImplementationKind.DisposePatternOnBase, disposePattern); 173 | } 174 | else if (disposePattern.IsSealed) 175 | { 176 | return (DisposePatternImplementationKind.SealedDisposePatternOnBase, disposePattern); 177 | } 178 | else // non overridable 179 | { 180 | return (DisposePatternImplementationKind.NonOverridableDisposePatternOnBase, disposePattern); 181 | } 182 | 183 | type = type.BaseType; 184 | } 185 | 186 | return (DisposePatternImplementationKind.None, null); 187 | } 188 | 189 | public static (DisposeImplementationKind, IMethodSymbol) GetDisposableImplementation(this INamedTypeSymbol sourceType) 190 | { 191 | var type = sourceType; 192 | 193 | while (type != null) 194 | { 195 | var dispose = type 196 | .GetMembers() 197 | .OfType() 198 | .FirstOrDefault(method => (method.Name == "Dispose" && method.Parameters.None()) || method.Name == "System.IDisposable.Dispose"); 199 | 200 | if (dispose == null) 201 | { 202 | } 203 | else if (type == sourceType) 204 | { 205 | return (DisposeImplementationKind.Dispose, dispose); 206 | } 207 | else if (dispose.IsVirtual || (dispose.IsOverride && !dispose.IsSealed)) 208 | { 209 | return (DisposeImplementationKind.OverridableDisposeOnBase, dispose); 210 | } 211 | else // sealed or non overridable 212 | { 213 | return (DisposeImplementationKind.DisposeOnBase, dispose); 214 | } 215 | 216 | type = type.BaseType; 217 | } 218 | 219 | return (DisposeImplementationKind.None, null); 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Utils/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.CodeDom.Compiler; 19 | using System.Collections.Generic; 20 | using System.Linq; 21 | using System.Threading; 22 | using Microsoft.CodeAnalysis; 23 | 24 | namespace Uno.CodeGen.ClassLifecycle.Utils 25 | { 26 | internal static class StringExtensions 27 | { 28 | public static bool HasValue(this string text) 29 | => !string.IsNullOrWhiteSpace(text); 30 | 31 | public static string ToLowerCamelCase(this string text) 32 | { 33 | var chars = text?.ToArray(); 34 | if (chars?.Length == 0) 35 | { 36 | return ""; 37 | } 38 | 39 | chars[0] = char.ToLowerInvariant(chars[0]); 40 | return new string(chars); 41 | } 42 | 43 | public static string JoinBy(this IEnumerable values, string separator) 44 | => string.Join(separator, values); 45 | 46 | public static string JoinByEmpty(this IEnumerable values) 47 | => string.Join(string.Empty, values); 48 | 49 | public static IDisposable Indent(this IndentedTextWriter writer) 50 | { 51 | var capture = writer.Indent; 52 | writer.Indent += 1; 53 | return Disposable.Create(() => writer.Indent = capture); 54 | } 55 | 56 | public static IDisposable Block(this IndentedTextWriter writer) 57 | { 58 | var capture = writer.Indent; 59 | writer.Indent += 1; 60 | writer.WriteLine("{"); 61 | return Disposable.Create(() => 62 | { 63 | writer.WriteLine("}"); 64 | writer.Indent = capture; 65 | }); 66 | } 67 | 68 | public static IDisposable Block(this IndentedTextWriter writer, string text) 69 | { 70 | var capture = writer.Indent; 71 | writer.Indent += 1; 72 | writer.WriteLine(text); 73 | writer.WriteLine("{"); 74 | return Disposable.Create(() => 75 | { 76 | writer.WriteLine("}"); 77 | writer.Indent = capture; 78 | }); 79 | } 80 | 81 | public static IDisposable NameSpaceOf(this IndentedTextWriter writer, INamedTypeSymbol type) 82 | { 83 | return type.GetContainingTypes().Reverse().Aggregate(writer.Block($"namespace {type.ContainingNamespace}"), CreateContainingBlock); 84 | 85 | IDisposable CreateContainingBlock(IDisposable previousLevel, INamedTypeSymbol containingType) 86 | { 87 | var containingTypeDisposable = writer.Block($"partial class {containingType.Name}"); 88 | 89 | return Disposable.Create(() => 90 | { 91 | containingTypeDisposable.Dispose(); 92 | previousLevel.Dispose(); 93 | }); 94 | } 95 | } 96 | 97 | private class Disposable : IDisposable 98 | { 99 | private Action _disposeAction; 100 | 101 | public static IDisposable Create(Action disposeAction) => new Disposable(disposeAction); 102 | 103 | private Disposable(Action disposeAction) => _disposeAction = disposeAction; 104 | 105 | /// 106 | public void Dispose() => Interlocked.Exchange(ref _disposeAction, null)?.Invoke(); 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.ClassLifecycle/Utils/SymbolNames.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | 20 | namespace Uno.CodeGen.ClassLifecycle.Utils 21 | { 22 | internal class SymbolNames 23 | { 24 | public SymbolNames(string name, string genericArguments, string nameWithGenerics, string forXml, string nameDefinition, string filename, string filePath) 25 | { 26 | Name = name; 27 | GenericArguments = genericArguments; 28 | NameWithGenerics = nameWithGenerics; 29 | ForXml = forXml; 30 | NameDefinition = nameDefinition; 31 | Filename = filename; 32 | FilePath = filePath; 33 | } 34 | 35 | public string Name { get; } 36 | 37 | /// 38 | /// MyType<T1, T2> 39 | /// 40 | public string NameWithGenerics { get; } // MyType 41 | 42 | /// 43 | /// MyType<,> 44 | /// 45 | public string NameDefinition { get; } // MyType<,> 46 | 47 | /// 48 | /// <T1, T2> 49 | /// 50 | public string GenericArguments { get; } // 51 | 52 | /// 53 | /// MyType&lt;T1, T2&gt; 54 | /// 55 | public string ForXml { get; } // MyType<T1, T2> 56 | 57 | /// 58 | /// MyType_T1_T2 59 | /// 60 | public string Filename { get; } // MyType_T1_T2 61 | 62 | public string FilePath { get; } 63 | } 64 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/AbstractExternalClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses 18 | { 19 | [GeneratedImmutable] 20 | public abstract partial class AbstractExternalClass 21 | { 22 | [EqualityHash] 23 | public string Id { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/AbstractExternalGenericClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses 18 | { 19 | [GeneratedImmutable] 20 | public abstract partial class AbstractExternalGenericClass 21 | { 22 | [EqualityHash] 23 | public TId Id { get; } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/ConcreteExternalClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses 18 | { 19 | [GeneratedImmutable] 20 | public partial class ConcreteExternalClass 21 | { 22 | [EqualityHash] 23 | public string Id { get; } 24 | } 25 | 26 | [GeneratedImmutable] 27 | public partial class ConcreteExternalClassNoHash 28 | { 29 | public string Id { get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/ConcreteExternalGenericClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses 18 | { 19 | [GeneratedImmutable] 20 | public abstract partial class ConcreteExternalGenericClass 21 | { 22 | [EqualityHash] 23 | public TId Id { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/MyViewModel.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace Uno.CodeGen.Tests.ExternalClasses 21 | { 22 | public partial class MyViewModel 23 | { 24 | // Properties 25 | [Inject] public string MyStringProperty { get; private set; } 26 | [Inject] public bool MyBooleanProperty { get; private set; } 27 | [Inject] public int MyIntegerProperty { get; private set; } 28 | [Inject] public DateTime MyDateTimeProperty { get; private set; } 29 | [Inject("name")] public object MyObjectProperty { get; private set; } 30 | [Inject] public Func MyFuncStringProperty { get; private set; } 31 | [Inject] public List MyListStringProperty { get; private set; } 32 | 33 | // Fields 34 | [Inject] public string MyStringField; 35 | [Inject] public bool MyBooleanField; 36 | [Inject] public int MyIntegerField; 37 | [Inject] public DateTime MyDateTimeField; 38 | [Inject("name")] public object MyObjectField; 39 | [Inject] public Func MyFuncStringField; 40 | [Inject] public List MyListStringField; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/SubNamespace/ConcreteExternalClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses.SubNamespace 18 | { 19 | [GeneratedImmutable] 20 | public partial class ConcreteExternalClass 21 | { 22 | [EqualityHash] 23 | public string Id { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/SubNamespace/ConcreteExternalGenericClass.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests.ExternalClasses.SubNamespace 18 | { 19 | [GeneratedImmutable] 20 | public abstract partial class ConcreteExternalGenericClass 21 | { 22 | [EqualityHash] 23 | public TId Id { get; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.ExternalClasses/Uno.CodeGen.Tests.ExternalClasses.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;netstandard2.0;netstandard1.3 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | all 18 | runtime; build; native; contentfiles; analyzers 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | false 33 | true 34 | TargetFramework 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.JsonDisabled/JsonTestObj.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | [assembly:Uno.ImmutableGenerationOptions(GenerateNewtownsoftJsonNetConverters = false, GenerateSystemTextJsonConverters = false)] 19 | 20 | namespace Uno.CodeGen.Tests.JsonDisabled 21 | { 22 | [GeneratedImmutable] 23 | public partial class JsonTestObj 24 | { 25 | public Type T { get; } 26 | 27 | public JsonTestObjChild Entity { get; } = JsonTestObjChild.Default; 28 | 29 | public bool IsSomething { get; } = true; 30 | 31 | } 32 | 33 | [GeneratedImmutable] 34 | public partial class JsonTestObjChild 35 | { 36 | public int MyField1 { get; } = 4; 37 | 38 | public int MyField2 { get; } = 75; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.JsonDisabled/Uno.CodeGen.Tests.JsonDisabled.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | false 29 | true 30 | TargetFramework 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.MinimalDeps/JsonTestObj.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno.CodeGen.Tests.MinimalDeps 20 | { 21 | [GeneratedImmutable] 22 | public partial class JsonTestObj 23 | { 24 | public Type T { get; } 25 | 26 | public JsonTestObjChild Entity { get; } = JsonTestObjChild.Default; 27 | 28 | public bool IsSomething { get; } = true; 29 | 30 | } 31 | 32 | [GeneratedImmutable] 33 | public partial class JsonTestObjChild 34 | { 35 | public int MyField1 { get; } = 4; 36 | 37 | public int MyField2 { get; } = 75; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests.MinimalDeps/Uno.CodeGen.Tests.MinimalDeps.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netstandard2.0;netstandard1.3 5 | false 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | false 35 | true 36 | TargetFramework 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.CustomComparers.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests 18 | { 19 | public partial class Given_GeneratedEquality 20 | { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.DerivedTypes.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using Uno.Equality; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_GeneratedEquality 24 | { 25 | [TestMethod] 26 | public void Equality_WhenUsingDifferentDerivedTypes() 27 | { 28 | var d1 = new MyDerived1.Builder { a = 10, b = 15, }.ToImmutable(); 29 | var d2 = new MyDerived2.Builder { a = 10, c = 25, }.ToImmutable(); 30 | var d3 = new MyDerived3.Builder { a = 10, b = 15, c=25 }.ToImmutable(); 31 | 32 | (d1 == d2).Should().BeFalse("d1 == d2"); 33 | (d2 == d1).Should().BeFalse("d2 == d1"); 34 | (d1 != d2).Should().BeTrue("d1 != d2"); 35 | (d2 != d1).Should().BeTrue("d2 != d1"); 36 | d1.Should().NotBe(d2, "d1.Equals(d2)"); 37 | d2.Should().NotBe(d1, "d2.Equals(d1)"); 38 | (d1 == d3).Should().BeFalse("d1 == d3"); 39 | (d3 == d1).Should().BeFalse("d3 == d1"); 40 | (d1 != d3).Should().BeTrue("d1 == d3"); 41 | (d3 != d1).Should().BeTrue("d3 == d1"); 42 | d1.Should().NotBe(d3, "d1.Equals(d3)"); 43 | d3.Should().NotBe(d1, "d3.Equals(d1)"); 44 | } 45 | 46 | [TestMethod] 47 | public void Equality_WhenUsingDerivedFromExternal() 48 | { 49 | var d1 = new MyADerived.Builder { Id = "d1", a = 15, }.ToImmutable(); 50 | var d2 = new MyADerived.Builder { Id = "d2", a = 15, }.ToImmutable(); 51 | 52 | (d1 == d2).Should().BeFalse("d1 == d2"); 53 | (d2 == d1).Should().BeFalse("d2 == d1"); 54 | (d1 != d2).Should().BeTrue("d1 != d2"); 55 | (d2 != d1).Should().BeTrue("d2 != d1"); 56 | d1.Should().NotBe(d2, "d1.Equals(d2)"); 57 | d2.Should().NotBe(d1, "d2.Equals(d1)"); 58 | } 59 | } 60 | 61 | [GeneratedImmutable] 62 | internal partial class MyBase 63 | { 64 | public int a { get; } 65 | } 66 | internal partial class MyDerived1 : MyBase 67 | { 68 | public int b { get; } 69 | } 70 | internal partial class MyDerived2 : MyBase 71 | { 72 | public int c { get; } 73 | } 74 | internal partial class MyDerived3 : MyDerived1 75 | { 76 | public int c { get; } 77 | } 78 | 79 | internal partial class MyADerived : Uno.CodeGen.Tests.ExternalClasses.ConcreteExternalClassNoHash 80 | { 81 | public int a { get; } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.Enums.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | 20 | namespace Uno.CodeGen.Tests 21 | { 22 | partial class Given_GeneratedEquality 23 | { 24 | 25 | [TestMethod] 26 | public void Equality_WithEnums() 27 | { 28 | var x1 = new MyClassWithEnums() {A = ByteEnum.No, B = SignedByteEnum.Present}; 29 | var x2 = new MyClassWithEnums() {A = ByteEnum.No, B = SignedByteEnum.Present}; 30 | var x3 = new MyClassWithEnums() {A = ByteEnum.Maybe, B = SignedByteEnum.Present}; 31 | var x4 = new MyClassWithEnums() {A = ByteEnum.Maybe, B = SignedByteEnum.Present}; 32 | var x5 = new MyClassWithEnums() {A = ByteEnum.Maybe, B = SignedByteEnum.Past}; 33 | 34 | var hash1 = x1.GetHashCode(); 35 | var hash2 = x2.GetHashCode(); 36 | var hash3 = x3.GetHashCode(); 37 | var hash4 = x4.GetHashCode(); 38 | var hash5 = x5.GetHashCode(); 39 | 40 | hash1.Should().Be(hash2); 41 | hash1.Should().NotBe(hash3); 42 | hash1.Should().NotBe(0); 43 | hash1.Should().NotBe(104729); 44 | hash3.Should().Be(hash4); 45 | hash3.Should().NotBe(hash5); 46 | } 47 | } 48 | internal enum ByteEnum : byte 49 | { 50 | Yes, 51 | No, 52 | Maybe, 53 | Always, 54 | Never 55 | } 56 | 57 | internal enum SignedByteEnum : sbyte 58 | { 59 | Past = -1, 60 | Present = 0, 61 | Future = 1 62 | } 63 | 64 | [GeneratedEquality] 65 | internal partial class MyClassWithEnums 66 | { 67 | [EqualityHash] 68 | internal ByteEnum A { get; set; } 69 | 70 | [EqualityHash] 71 | internal SignedByteEnum B { get; set; } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.Indexer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.CodeGen.Tests 18 | { 19 | [GeneratedEquality] 20 | public partial class MyEntityWithIndexer 21 | { 22 | public string this[string key] => null; 23 | } 24 | 25 | partial class Given_GeneratedEquality 26 | { 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.KeyEquality.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using Uno.Equality; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_GeneratedEquality 24 | { 25 | [TestMethod] 26 | public void KeyEquality_WhenUsingKeyEqualityMode() 27 | { 28 | var e1 = new KeyEqualityWrapper.Builder 29 | { 30 | IdField = new KeyEqualityId.Builder {Id = "a", Name = "n"}, 31 | NonKeyField = "nkf1" 32 | }.ToImmutable(); 33 | 34 | var e2 = new KeyEqualityWrapper.Builder 35 | { 36 | IdField = new KeyEqualityId.Builder { Id = "a", Name = "n-bis" }, 37 | NonKeyField = "nkf2" 38 | }.ToImmutable(); 39 | 40 | e1.Equals(e2).Should().BeFalse(); 41 | e1.KeyEquals(e2).Should().BeTrue(); 42 | } 43 | 44 | [TestMethod] 45 | public void KeyEquality_WhenUsingEqualityMode() 46 | { 47 | var e1 = new EqualityWrapper.Builder 48 | { 49 | IdField = new KeyEqualityId.Builder { Id = "a", Name = "n" }, 50 | NonKeyField = "nkf1" 51 | }.ToImmutable(); 52 | 53 | var e2 = new EqualityWrapper.Builder 54 | { 55 | IdField = new KeyEqualityId.Builder { Id = "a", Name = "n-bis" }, 56 | NonKeyField = "nkf2" 57 | }.ToImmutable(); 58 | 59 | e1.Equals(e2).Should().BeFalse(); 60 | e1.KeyEquals(e2).Should().BeFalse(); 61 | e1.IdField.KeyEquals(e2.IdField).Should().BeTrue(); 62 | } 63 | 64 | //[TestMethod] 65 | //public void KeyEquality_WhenUsingKeyEqualityMode_OnAbstractClass() 66 | //{ 67 | // var e1 = new KeyEqualityConcreteWrapper.Builder 68 | // { 69 | // IdField = new KeyEqualityId.Builder { Id = "a", Name = "n" }, 70 | // NonKeyField = "nkf1" 71 | // }.ToImmutable(); 72 | 73 | // var e2 = new KeyEqualityWrapper.Builder 74 | // { 75 | // IdField = new KeyEqualityConcreteWrapper.Builder { Id = "a", Name = "n-bis" }, 76 | // NonKeyField = "nkf2" 77 | // }.ToImmutable(); 78 | 79 | // e1.Equals(e2).Should().BeFalse(); 80 | // e1.KeyEquals(e2).Should().BeTrue(); 81 | //} 82 | } 83 | 84 | [GeneratedImmutable] 85 | public partial class KeyEqualityWrapper 86 | { 87 | [EqualityKey] 88 | public KeyEqualityId IdField { get; } 89 | 90 | public string NonKeyField { get; } 91 | } 92 | 93 | [GeneratedImmutable] 94 | public partial class EqualityWrapper 95 | { 96 | [EqualityKey(KeyEqualityMode.UseEquality)] 97 | public KeyEqualityId IdField { get; } 98 | 99 | public string NonKeyField { get; } 100 | } 101 | 102 | [GeneratedImmutable] 103 | public partial class KeyEqualityId 104 | { 105 | [EqualityKey] 106 | public string Id { get; } 107 | 108 | public string Name { get; } 109 | } 110 | 111 | [GeneratedImmutable] 112 | public abstract partial class KeyEqualityAbstractWrapper 113 | where T:IKeyEquatable 114 | { 115 | [EqualityKey] 116 | public T IdField { get; } 117 | 118 | public string NonKeyField { get; } 119 | } 120 | 121 | [GeneratedImmutable] 122 | public abstract partial class KeyEqualityConcreteAbstractWrapper : KeyEqualityAbstractWrapper 123 | { 124 | public string NonKeyField2 { get; } 125 | } 126 | 127 | [GeneratedImmutable] 128 | public partial class KeyEqualityConcreteWrapper : KeyEqualityConcreteAbstractWrapper 129 | { 130 | public string NonKeyField3 { get; } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.Strings.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using Uno.Equality; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_GeneratedEquality 24 | { 25 | [TestMethod] 26 | public void Equality_WhenUsingMyEntityForStringComparison() 27 | { 28 | new MyEntityForStringComparison.Builder {DefaultMode = "a"}.ToImmutable() 29 | .Equals(new MyEntityForStringComparison.Builder {DefaultMode = "a"}.ToImmutable()).Should().BeTrue(); 30 | 31 | new MyEntityForStringComparison.Builder {DefaultMode = "a"}.ToImmutable() 32 | .Equals(new MyEntityForStringComparison.Builder {DefaultMode = "A"}.ToImmutable()).Should().BeFalse(); 33 | 34 | new MyEntityForStringComparison.Builder {DefaultMode = ""}.ToImmutable() 35 | .Equals(MyEntityForStringComparison.Default).Should().BeFalse(); 36 | 37 | new MyEntityForStringComparison.Builder {IgnoreCase = "a"}.ToImmutable() 38 | .Equals(new MyEntityForStringComparison.Builder {IgnoreCase = "a"}.ToImmutable()).Should().BeTrue(); 39 | 40 | new MyEntityForStringComparison.Builder {IgnoreCase = "a"}.ToImmutable() 41 | .Equals(new MyEntityForStringComparison.Builder {IgnoreCase = "A"}.ToImmutable()).Should().BeTrue(); 42 | 43 | new MyEntityForStringComparison.Builder {IgnoreCase = ""}.ToImmutable() 44 | .Equals(MyEntityForStringComparison.Default).Should().BeFalse(); 45 | 46 | new MyEntityForStringComparison.Builder {EmptyEqualsNull = "a"}.ToImmutable() 47 | .Equals(new MyEntityForStringComparison.Builder {EmptyEqualsNull = "a"}.ToImmutable()).Should().BeTrue(); 48 | 49 | new MyEntityForStringComparison.Builder {EmptyEqualsNull = "a"}.ToImmutable() 50 | .Equals(new MyEntityForStringComparison.Builder {EmptyEqualsNull = "A"}.ToImmutable()).Should().BeFalse(); 51 | 52 | new MyEntityForStringComparison.Builder {EmptyEqualsNull = ""}.ToImmutable() 53 | .Equals(MyEntityForStringComparison.Default).Should().BeTrue(); 54 | 55 | new MyEntityForStringComparison.Builder {EmptyEqualsNull = ""}.ToImmutable() 56 | .Should().BeSameAs(MyEntityForStringComparison.Default); 57 | 58 | new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = "a"}.ToImmutable() 59 | .Equals(new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = "a"}.ToImmutable()).Should().BeTrue(); 60 | 61 | new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = "a"}.ToImmutable() 62 | .Equals(new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = "A"}.ToImmutable()).Should().BeTrue(); 63 | 64 | new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = ""}.ToImmutable() 65 | .Equals(MyEntityForStringComparison.Default).Should().BeTrue(); 66 | 67 | new MyEntityForStringComparison.Builder {EmptyEqualsNullIgnoreCase = ""}.ToImmutable() 68 | .Should().BeSameAs(MyEntityForStringComparison.Default); 69 | } 70 | 71 | [TestMethod] 72 | public void Equality_WhenUsingMyEntityForStringHashcodeComparison() 73 | { 74 | new MyEntityForStringComparison.Builder { DefaultMode = "a" }.ToImmutable().GetHashCode() 75 | .Should().Be(new MyEntityForStringComparison.Builder { DefaultMode = "a" }.ToImmutable().GetHashCode(), "DefaultMode: a == a"); 76 | 77 | new MyEntityForStringComparison.Builder { DefaultMode = "a" }.ToImmutable().GetHashCode() 78 | .Should().NotBe(new MyEntityForStringComparison.Builder { DefaultMode = "A" }.ToImmutable().GetHashCode(), "DefaultMode: a != A"); 79 | 80 | new MyEntityForStringComparison.Builder { DefaultMode = "" }.ToImmutable().GetHashCode() 81 | .Should().NotBe(MyEntityForStringComparison.Default.GetHashCode(), "DefaultMode: \"\" != null"); 82 | 83 | new MyEntityForStringComparison.Builder { IgnoreCase = "a" }.ToImmutable().GetHashCode() 84 | .Should().Be(new MyEntityForStringComparison.Builder { IgnoreCase = "a" }.ToImmutable().GetHashCode(), "IgnoreCase: a == a"); 85 | 86 | new MyEntityForStringComparison.Builder { IgnoreCase = "a" }.ToImmutable().GetHashCode() 87 | .Should().Be(new MyEntityForStringComparison.Builder { IgnoreCase = "A" }.ToImmutable().GetHashCode(), "IgnoreCase: a == A"); 88 | 89 | new MyEntityForStringComparison.Builder { IgnoreCase = "" }.ToImmutable().GetHashCode() 90 | .Should().NotBe(MyEntityForStringComparison.Default.GetHashCode(), "IgnoreCase: \"\" != null"); 91 | 92 | new MyEntityForStringComparison.Builder { EmptyEqualsNull = "a" }.ToImmutable().GetHashCode() 93 | .Should().Be(new MyEntityForStringComparison.Builder { EmptyEqualsNull = "a" }.ToImmutable().GetHashCode(), "EmptyEqualsNull: a == a"); 94 | 95 | new MyEntityForStringComparison.Builder { EmptyEqualsNull = "a" }.ToImmutable().GetHashCode() 96 | .Should().NotBe(new MyEntityForStringComparison.Builder { EmptyEqualsNull = "A" }.ToImmutable().GetHashCode(), "EmptyEqualsNull: a != A"); 97 | 98 | new MyEntityForStringComparison.Builder { EmptyEqualsNull = "" }.ToImmutable().GetHashCode() 99 | .Should().Be(MyEntityForStringComparison.Default.GetHashCode(), "EmptyEqualsNull: \"\" == null"); 100 | 101 | new MyEntityForStringComparison.Builder { EmptyEqualsNullIgnoreCase = "a" }.ToImmutable().GetHashCode() 102 | .Should().Be(new MyEntityForStringComparison.Builder { EmptyEqualsNullIgnoreCase = "a" }.ToImmutable().GetHashCode(), "EmptyEqualsNullIgnoreCase: a == a"); 103 | 104 | new MyEntityForStringComparison.Builder { EmptyEqualsNullIgnoreCase = "a" }.ToImmutable().GetHashCode() 105 | .Should().Be(new MyEntityForStringComparison.Builder { EmptyEqualsNullIgnoreCase = "A" }.ToImmutable().GetHashCode(), "EmptyEqualsNullIgnoreCase: a == A"); 106 | 107 | new MyEntityForStringComparison.Builder { EmptyEqualsNullIgnoreCase = "" }.ToImmutable().GetHashCode() 108 | .Should().Be(MyEntityForStringComparison.Default.GetHashCode(), "EmptyEqualsNullIgnoreCase: \"\" == null"); 109 | } 110 | } 111 | 112 | [GeneratedImmutable(GenerateEquality = true)] 113 | public partial class MyEntityForStringComparison 114 | { 115 | [EqualityComparerOptions(StringMode = StringComparerMode.Default)] 116 | [EqualityHash] 117 | public string DefaultMode { get; } 118 | 119 | [EqualityComparerOptions(StringMode = StringComparerMode.IgnoreCase)] 120 | [EqualityHash] 121 | public string IgnoreCase { get; } 122 | 123 | [EqualityComparerOptions(StringMode = StringComparerMode.EmptyEqualsNull)] 124 | [EqualityHash] 125 | public string EmptyEqualsNull { get; } 126 | 127 | [EqualityComparerOptions(StringMode = StringComparerMode.EmptyEqualsNull | StringComparerMode.IgnoreCase)] 128 | [EqualityHash] 129 | public string EmptyEqualsNullIgnoreCase { get; } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_GeneratedEquality.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.ComponentModel.DataAnnotations; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | namespace Uno.CodeGen.Tests 23 | { 24 | [TestClass] 25 | public partial class Given_GeneratedEquality 26 | { 27 | // Check other files 28 | } 29 | 30 | [GeneratedEquality] 31 | internal partial class MyEqualityClass 32 | { 33 | [EqualityKey] 34 | internal string A { get; set; } 35 | 36 | private static int GetHash_A(string value) => -1; 37 | 38 | private static IEqualityComparer A_CustomComparer => StringComparer.OrdinalIgnoreCase; 39 | 40 | [EqualityKey] 41 | internal int B { get; set; } 42 | 43 | [EqualityHash] 44 | internal bool C { get; set; } 45 | 46 | [EqualityHash] 47 | internal string D { get; set; } 48 | 49 | private static IEqualityComparer D_CustomComparer => StringComparer.OrdinalIgnoreCase; 50 | 51 | [EqualityHash] 52 | internal TSomething E { get; set; } 53 | 54 | private static IEqualityComparer E_CustomComparer => EqualityComparer.Default; 55 | 56 | [EqualityHash] 57 | internal bool[] F { get; set; } 58 | 59 | [EqualityHash] 60 | internal IEnumerable G { get; set; } 61 | 62 | [EqualityHash] 63 | internal ICollection H { get; set; } 64 | } 65 | 66 | [GeneratedEquality] 67 | internal partial class DerivedEqualityClass : MyEqualityClass 68 | { 69 | } 70 | 71 | [GeneratedEquality] 72 | internal partial struct MyEqualityStruct 73 | { 74 | [EqualityKey] 75 | internal string A { get; } 76 | 77 | [Key] 78 | internal string B { get; } 79 | } 80 | } -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.Fields.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System.Collections.Generic; 18 | 19 | namespace Uno.CodeGen.Tests 20 | { 21 | [GeneratedImmutable] 22 | internal partial class MyEntityWithFields 23 | { 24 | private readonly IReadOnlyDictionary _readonlyField; 25 | 26 | public MyEntityWithFields(IReadOnlyDictionary readonlyField) 27 | { 28 | _readonlyField = readonlyField; 29 | } 30 | } 31 | 32 | partial class Given_ImmutableEntity 33 | { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.GenericsAndAbstract.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System.Collections.Generic; 18 | using System.ComponentModel.DataAnnotations; 19 | 20 | namespace Uno.CodeGen.Tests 21 | { 22 | public partial class Given_ImmutableEntity 23 | { 24 | } 25 | 26 | [GeneratedImmutable] 27 | public abstract partial class GenericFieldImmutable 28 | { 29 | public T Entity { get; } 30 | } 31 | 32 | [GeneratedImmutable(GenerateEquality = false)] 33 | public partial class GenericToNonGenericDerivedImmutable : GenericFieldImmutable 34 | { 35 | } 36 | 37 | [GeneratedImmutable] 38 | public partial class AnotherGenericToNonGenericDerivedImmutable : GenericFieldImmutable 39 | { 40 | } 41 | 42 | [ImmutableAttributeCopyIgnore("RequiredAttribute")] 43 | [GeneratedImmutable()] 44 | public abstract partial class AbstractImmutableTypeWithManyGenerics 45 | where T1 : MyImmutableEntity 46 | where T2 : T1 47 | where T3 : IReadOnlyCollection 48 | { 49 | [Required, System.ComponentModel.DataAnnotations.DataType(DataType.Text)] 50 | [System.ComponentModel.DataAnnotations.Key] 51 | [System.ComponentModel.DataAnnotations.RegularExpression("regex-pattern", ErrorMessage = "error-msg")] 52 | public string Id { get; } 53 | 54 | [Required(AllowEmptyStrings = true, ErrorMessage = "Entity1 is required!")] 55 | public T1 Entity1 { get; } 56 | 57 | [EqualityIgnore] 58 | public T2 Entity2 { get; } 59 | 60 | [EqualityIgnore] 61 | public T3 Entity3 { get; } 62 | 63 | [EqualityIgnore] 64 | public T4 Entity4 { get; } 65 | 66 | [EqualityIgnore] 67 | public T5 Entity5 { get; } 68 | 69 | [EqualityHash] 70 | public T6 Entity6 { get; } 71 | 72 | public (T1, T2, T3, T4, T5, T6) Values { get; } 73 | 74 | private static int GetHash_Entity6(T6 value) => 50; 75 | } 76 | 77 | public partial class ConcreteGenericImmutable : AbstractImmutableTypeWithManyGenerics 78 | where T : IReadOnlyCollection 79 | { 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.Inheritance.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using FluentAssertions; 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; 20 | using Uno.Equality; 21 | using AbstractExternalClass = Uno.CodeGen.Tests.ExternalClasses.AbstractExternalClass; 22 | 23 | namespace Uno.CodeGen.Tests 24 | { 25 | public partial class Given_ImmutableEntity 26 | { 27 | [TestMethod] 28 | public void Immutable_When_Abstracted_Base_Class() 29 | { 30 | InheritanceDerivedClassFromExternal sut1 = InheritanceDerivedClassFromExternal.Default.WithId("id1"); 31 | InheritanceDerivedClassFromExternal sut2 = new InheritanceDerivedClassFromExternal.Builder() {Id = "id1"}; 32 | 33 | sut1.Equals(sut2).Should().BeTrue(); 34 | } 35 | } 36 | 37 | [GeneratedImmutable] 38 | public abstract partial class InheritanceAbstractBaseClass 39 | where T : IKeyEquatable 40 | { 41 | [EqualityKey] 42 | public T KeyValue { get; } 43 | } 44 | 45 | [GeneratedImmutable] 46 | public abstract partial class InheritanceAbstractBaseClass2 : InheritanceAbstractBaseClass 47 | where T : IKeyEquatable 48 | { 49 | } 50 | 51 | [GeneratedImmutable] 52 | public partial class InheritanceHashedClass 53 | { 54 | [EqualityKey] 55 | public string Id { get; } 56 | } 57 | 58 | [GeneratedImmutable] 59 | public partial class InheritanceDerivedClass : InheritanceAbstractBaseClass 60 | { 61 | } 62 | 63 | public partial class InheritanceDerivedClassFromExternal : AbstractExternalClass 64 | { 65 | public string Str { get; } 66 | public AbstractExternalClass Class1 { get; } 67 | public Uri Uri { get; } 68 | public int Int { get; } 69 | 70 | public (string a, int b, Uri c, AbstractExternalClass d, DateTime e, DateTimeOffset f, DateTimeKind g) SuperTuple { get; } 71 | } 72 | 73 | public partial class InheritanceDerivedClassFromExternalGeneric : ExternalClasses.AbstractExternalGenericClass 74 | { 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.Newtownsoft.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using Newtonsoft.Json; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_ImmutableEntity 24 | { 25 | [TestMethod] 26 | public void Immutable_When_Serializing_A_Using_JsonNet() 27 | { 28 | var json = JsonConvert.SerializeObject(A.Default.WithEntity(x => null).ToImmutable()); 29 | 30 | json.Should().BeEquivalentTo("{\"T\":null,\"Entity\":null,\"IsSomething\":true,\"Metadata\":null}"); 31 | } 32 | 33 | [TestMethod] 34 | public void Immutable_When_Serializing_ABuilder_Using_JsonNet() 35 | { 36 | var json = JsonConvert.SerializeObject(A.Default.WithEntity(x => null)); 37 | 38 | json.Should().BeEquivalentTo("{\"T\":null,\"Entity\":null,\"IsSomething\":true,\"Metadata\":null}"); 39 | } 40 | 41 | [TestMethod] 42 | public void Immutable_When_Deserializing_ABuilder_Using_JsonNet() 43 | { 44 | const string json = "{IsSomething:false, T:null, Entity:{MyField1:1, MyField2:2}}"; 45 | var a = JsonConvert.DeserializeObject(json).ToImmutable(); 46 | a.Should().NotBeNull(); 47 | a.IsSomething.Should().BeFalse(); 48 | a.T.Should().BeNull(); 49 | a.Entity.Should().NotBeNull(); 50 | a.Entity­.MyField1.Should().Be(1); 51 | a.Entity­.MyField2.Should().Be(2); 52 | } 53 | 54 | [TestMethod] 55 | public void Immutable_When_Deserializing_A_Using_JsonNet() 56 | { 57 | const string json = "{IsSomething:false, T:null, Entity:{MyField1:1, MyField2:2}}"; 58 | var a = JsonConvert.DeserializeObject(json); 59 | a.Should().NotBeNull(); 60 | a.IsSomething.Should().BeFalse(); 61 | a.T.Should().BeNull(); 62 | a.Entity.Should().NotBeNull(); 63 | a.Entity­.MyField1.Should().Be(1); 64 | a.Entity­.MyField2.Should().Be(2); 65 | } 66 | 67 | [TestMethod] 68 | public void Immutable_When_Deserializing_ABuilder_WithNull_Using_JsonNet() 69 | { 70 | const string json = "{IsSomething:false, T:null, Entity:null}"; 71 | var a = JsonConvert.DeserializeObject(json).ToImmutable(); 72 | a.Should().NotBeNull(); 73 | a.IsSomething.Should().BeFalse(); 74 | a.T.Should().BeNull(); 75 | a.Entity.Should().BeNull(); 76 | } 77 | 78 | [TestMethod] 79 | public void Immutable_When_Deserializing_A_WithNull_Using_JsonNet() 80 | { 81 | const string json = "{IsSomething:false, T:null, Entity:null}"; 82 | var a = JsonConvert.DeserializeObject(json); 83 | a.Should().NotBeNull(); 84 | a.IsSomething.Should().BeFalse(); 85 | a.T.Should().BeNull(); 86 | a.Entity.Should().BeNull(); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.Options.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System.Collections.Immutable; 18 | using FluentAssertions; 19 | using Microsoft.VisualStudio.TestTools.UnitTesting; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_ImmutableEntity 24 | { 25 | [TestMethod] 26 | public void Immutable_When_Using_Options() 27 | { 28 | var list = ImmutableList.Empty; 29 | 30 | var original = MyImmutableEntity.None; 31 | var modifiedBuilder = original.WithList(list); 32 | Option modifiedOption = modifiedBuilder; 33 | MyImmutableEntity modified = modifiedOption; 34 | 35 | original.MatchNone().Should().BeTrue(); 36 | modifiedOption.MatchSome().Should().BeTrue(); 37 | modified.MyField1.Should().Be(MyImmutableEntity.Default.MyField1); 38 | modified.MyField2.Should().Be(MyImmutableEntity.Default.MyField2); 39 | modified.Date.Should().Be(MyImmutableEntity.Default.Date); 40 | modified.List.Should().BeSameAs(list); 41 | } 42 | 43 | [TestMethod] 44 | public void Immutable_When_Using_OptionNone() 45 | { 46 | MyImmutableEntity.Builder builder = MyImmutableEntity.None; 47 | Option option = builder; 48 | option.MatchNone().Should().BeTrue(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.SystemTextJson.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using FluentAssertions; 18 | using Microsoft.VisualStudio.TestTools.UnitTesting; 19 | using System.Text.Json; 20 | 21 | namespace Uno.CodeGen.Tests 22 | { 23 | public partial class Given_ImmutableEntity 24 | { 25 | [TestMethod] 26 | public void Immutable_When_Serializing_A_Using_SystemTextJson() 27 | { 28 | var json = JsonSerializer.Serialize(A.Default.WithEntity(x => null).ToImmutable()); 29 | 30 | json.Should().BeEquivalentTo("{\"T\":null,\"Entity\":null,\"IsSomething\":true,\"Metadata\":null}"); 31 | } 32 | 33 | [TestMethod] 34 | public void Immutable_When_Serializing_ABuilder_Using_SystemTextJson() 35 | { 36 | var json = JsonSerializer.Serialize(A.Default.WithEntity(x => null)); 37 | 38 | json.Should().BeEquivalentTo("{\"T\":null,\"Entity\":null,\"IsSomething\":true,\"Metadata\":null}"); 39 | } 40 | 41 | [TestMethod] 42 | public void Immutable_When_Deserializing_ABuilder_Using_SystemTextJson() 43 | { 44 | const string json = "{\"IsSomething\":false, \"T\":null, \"Entity\":{\"MyField1\":1, \"MyField2\":2}}"; 45 | var a = JsonSerializer.Deserialize(json).ToImmutable(); 46 | a.Should().NotBeNull(); 47 | a.IsSomething.Should().BeFalse(); 48 | a.T.Should().BeNull(); 49 | a.Entity.Should().NotBeNull(); 50 | a.Entity­.MyField1.Should().Be(1); 51 | a.Entity­.MyField2.Should().Be(2); 52 | } 53 | 54 | [TestMethod] 55 | public void Immutable_When_Deserializing_A_Using_SystemTextJson() 56 | { 57 | const string json = "{\"IsSomething\":false, \"T\":null, \"Entity\":{\"MyField1\":1, \"MyField2\":2}}"; 58 | var a = JsonSerializer.Deserialize(json); 59 | a.Should().NotBeNull(); 60 | a.IsSomething.Should().BeFalse(); 61 | a.T.Should().BeNull(); 62 | a.Entity.Should().NotBeNull(); 63 | a.Entity­.MyField1.Should().Be(1); 64 | a.Entity­.MyField2.Should().Be(2); 65 | } 66 | 67 | [TestMethod] 68 | public void Immutable_When_Deserializing_ABuilder_WithNull_Using_SystemTextJson() 69 | { 70 | const string json = "{\"IsSomething\":false, \"T\":null, \"Entity\":null}"; 71 | var a = JsonSerializer.Deserialize(json).ToImmutable(); 72 | a.Should().NotBeNull(); 73 | a.IsSomething.Should().BeFalse(); 74 | a.T.Should().BeNull(); 75 | a.Entity.Should().BeNull(); 76 | } 77 | 78 | [TestMethod] 79 | public void Immutable_When_Deserializing_A_WithNull_Using_SystemTextJson() 80 | { 81 | const string json = "{\"IsSomething\":false, \"T\":null, \"Entity\":null}"; 82 | var a = JsonSerializer.Deserialize(json); 83 | a.Should().NotBeNull(); 84 | a.IsSomething.Should().BeFalse(); 85 | a.T.Should().BeNull(); 86 | a.Entity.Should().BeNull(); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.TreatAsImmutable.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Net.Mail; 19 | using Uno; 20 | 21 | [assembly: TreatAsImmutable(typeof(DivideByZeroException))] 22 | 23 | namespace Uno.CodeGen.Tests 24 | { 25 | partial class Given_ImmutableEntity 26 | { 27 | internal static readonly MyImmutableWithExternalTreatAsImmutable TreatAsImmutable = 28 | MyImmutableWithExternalTreatAsImmutable.Default; 29 | } 30 | 31 | [GeneratedImmutable] 32 | internal partial class MyImmutableWithExternalTreatAsImmutable 33 | { 34 | private DivideByZeroException Exception { get; } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_ImmutableEntity.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Collections.Immutable; 20 | using FluentAssertions; 21 | using Microsoft.VisualStudio.TestTools.UnitTesting; 22 | using Uno.Equality; 23 | 24 | [assembly: Uno.ImmutableGenerationOptions(TreatArrayAsImmutable = true, GenerateEqualityByDefault = true)] 25 | 26 | namespace Uno.CodeGen.Tests 27 | { 28 | [TestClass] 29 | public partial class Given_ImmutableEntity 30 | { 31 | [TestMethod] 32 | public void Immutable_When_CreatingFromBuilder_WithDefaultValue() 33 | { 34 | var entity = new MyImmutableEntity.Builder().ToImmutable(); 35 | 36 | entity.Should().NotBeNull(); 37 | entity.MyField1.Should().Be(4); 38 | } 39 | 40 | [TestMethod] 41 | public void Immutable_When_CreatingFromBuilder_And_ImplicitlyCasted() 42 | { 43 | MyImmutableEntity entity = new MyImmutableEntity.Builder 44 | { 45 | MyField1 = 42 46 | }; 47 | 48 | entity.Should().NotBeNull(); 49 | entity.MyField1.Should().Be(42); 50 | } 51 | 52 | [TestMethod] 53 | public void Immutable_When_CreatingFromBuilder_TheResultIsCached() 54 | { 55 | var builder = new MyImmutableEntity.Builder 56 | { 57 | MyField1 = 42 58 | }; 59 | 60 | var r1 = builder.ToImmutable(); 61 | var r2 = builder.ToImmutable(); 62 | 63 | r1.Should().NotBeNull(); 64 | r1.MyField1.Should().Be(42); 65 | r1.Should().BeSameAs(r2); 66 | } 67 | 68 | [TestMethod] 69 | public void Immutable_When_CreatingABuilderFromExisting_And_NoChanges_Then_ReferenceIsSame() 70 | { 71 | MyImmutableEntity original = new MyImmutableEntity.Builder 72 | { 73 | MyField1 = 42 74 | }; 75 | 76 | var builder = new MyImmutableEntity.Builder(original); 77 | var newInstance = builder.ToImmutable(); 78 | 79 | newInstance.Should().BeSameAs(original); 80 | } 81 | 82 | [TestMethod] 83 | public void Immutable_When_CreatingABuilderFromExisting() 84 | { 85 | MyImmutableEntity original = new MyImmutableEntity.Builder 86 | { 87 | MyField1 = 42 88 | }; 89 | 90 | MyImmutableEntity newInstance = original 91 | .WithMyField1(43); 92 | 93 | original.MyField1.Should().Be(42); 94 | newInstance.MyField1.Should().Be(43); 95 | } 96 | 97 | [TestMethod] 98 | public void Immutable_When_CreatingHierarchyOfBuilders() 99 | { 100 | A original = A.Default.WithEntity(x => x.WithMyField2(223)); 101 | original.Entity.MyField2.Should().Be(223); 102 | } 103 | 104 | [TestMethod] 105 | public void Immutable_When_CreatingHierarchyOfBuilders_Then_NullRefException_Is_Prevented() 106 | { 107 | var list = ImmutableList.Empty; 108 | A a = null; 109 | 110 | var newObj = a.WithEntity(b => b.WithList(list)); 111 | 112 | newObj.Entity.List.Should().BeSameAs(list); 113 | } 114 | 115 | [TestMethod] 116 | public void Immutable_When_Using_Attributes_Then_They_Are_Copied_On_Builder() 117 | { 118 | var tBuilder = typeof(AbstractImmutableTypeWithManyGenerics.Builder); 119 | var idProperty = tBuilder.GetProperty("Id"); 120 | var attributes = idProperty.GetCustomAttributes(false); 121 | attributes.Should().HaveCount(3); 122 | } 123 | 124 | [TestMethod] 125 | public void Immutable_When_Assigning_EquivalentParameters() 126 | { 127 | ImmutableForTypeEquality original = ImmutableForTypeEquality.Default 128 | .WithString("str") 129 | .WithSortedBytes(new byte[] {1, 2, 3}) 130 | .WithUnsortedBytes(new byte[] {1, 2, 3}); 131 | 132 | ImmutableForTypeEquality modified = original 133 | .WithString("str") 134 | .WithSortedBytes(new byte[] { 1, 2, 3 }) 135 | .WithUnsortedBytes(new byte[] { 1, 2, 3 }); 136 | 137 | original.Should().BeEquivalentTo(modified); 138 | original.Should().BeSameAs(modified); 139 | } 140 | } 141 | 142 | [GeneratedImmutable] 143 | public partial class A 144 | { 145 | public Type T { get; } 146 | 147 | public MyImmutableEntity Entity { get; } = MyImmutableEntity.Default; 148 | 149 | public bool IsSomething { get; } = true; 150 | 151 | public IImmutableDictionary Metadata { get; } 152 | } 153 | 154 | public partial class B : A 155 | { 156 | public Uri FirstField { get; } 157 | 158 | public string SecondField { get; } 159 | 160 | public long ThirdField { get; } 161 | 162 | public TimeSpan TimeSpan { get; } 163 | 164 | public bool Boolean { get; } 165 | 166 | public DateTimeKind Enum { get; } 167 | 168 | public new bool IsSomething { get; } 169 | } 170 | 171 | [GeneratedImmutable] 172 | public partial class MyImmutableEntity 173 | { 174 | public int MyField1 { get; } = 4; 175 | 176 | public int MyField2 { get; } = 75; 177 | 178 | public int? MyField3 { get; } 179 | 180 | public string[] MyField4 { get; } 181 | 182 | public IReadOnlyList MyField5 { get; } 183 | 184 | public ImplicitlyImmutableClass MyField6 { get; } 185 | 186 | public ImplicitlyImmutableStruct MyField7 { get; } 187 | 188 | public int Sum => MyField1 + MyField2; // won't generate any builder code 189 | 190 | public DateTimeOffset Date { get; } = DateTimeOffset.Now; 191 | 192 | public ImmutableList List { get; } = ImmutableList.Create("a", "b"); 193 | } 194 | 195 | public class ImplicitlyImmutableClass 196 | { 197 | public ImplicitlyImmutableClass(string a, string b, int i) 198 | { 199 | A = a; 200 | B = b; 201 | I = i; 202 | } 203 | 204 | public string A { get; } 205 | 206 | public string B { get; } 207 | 208 | #pragma warning disable SA1401 // Fields must be private 209 | public readonly int I; 210 | #pragma warning restore SA1401 // Fields must be private 211 | } 212 | 213 | public struct ImplicitlyImmutableStruct 214 | { 215 | public ImplicitlyImmutableStruct(string a, string b, int i) 216 | { 217 | A = a; 218 | B = b; 219 | I = i; 220 | } 221 | 222 | public string A { get; } 223 | 224 | public string B { get; } 225 | 226 | public readonly int I; 227 | } 228 | 229 | [GeneratedImmutable] 230 | public partial class ImmutableForTypeEquality 231 | { 232 | public string String { get; } 233 | 234 | [EqualityComparerOptions(CollectionMode = CollectionComparerMode.Sorted)] 235 | public byte[] SortedBytes { get; } 236 | 237 | [EqualityComparerOptions(CollectionMode = CollectionComparerMode.Unsorted)] 238 | public byte[] UnsortedBytes { get; } 239 | } 240 | 241 | [GeneratedImmutable] 242 | public partial class ImmutableWithStaticProperties 243 | { 244 | public static ImmutableWithStaticProperties Version1 { get; } = Default; 245 | 246 | public static ImmutableWithStaticProperties Version2 { get; } = Default.WithVersion(2); 247 | 248 | public static ImmutableWithStaticProperties Version3 { get; } = Default.WithVersion(3); 249 | 250 | [EqualityKey] 251 | public int Version { get; } = 1; 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Given_Injectable.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.ComponentModel.DataAnnotations; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | using Uno.CodeGen.Tests.ExternalClasses; 22 | 23 | namespace Uno.CodeGen.Tests 24 | { 25 | [TestClass] 26 | public partial class Given_Injectable 27 | { 28 | [TestMethod] 29 | public void When_Injecting_Then_Injected() 30 | { 31 | var boolean = true; 32 | var integer = 42; 33 | var @string = "Hello world!"; 34 | var dateTime = DateTime.Now; 35 | var providedName = default(string); 36 | var strings = new List { "A", "B", "C" }; 37 | 38 | var vm = new MyViewModel(); 39 | 40 | (vm as IInjectable).Inject((type, name) => 41 | { 42 | if (type == typeof(bool)) 43 | { 44 | return boolean; 45 | } 46 | if (type == typeof(int)) 47 | { 48 | return integer; 49 | } 50 | if (type == typeof(string)) 51 | { 52 | return @string; 53 | } 54 | if (type == typeof(DateTime)) 55 | { 56 | return dateTime; 57 | } 58 | if (type == typeof(object)) 59 | { 60 | providedName = name; 61 | return name; 62 | } 63 | if (type == typeof(List)) 64 | { 65 | return strings; 66 | } 67 | 68 | throw new NotSupportedException(); 69 | }); 70 | 71 | // Properties 72 | Assert.AreEqual(boolean, vm.MyBooleanProperty); 73 | Assert.AreEqual(integer, vm.MyIntegerProperty); 74 | Assert.AreEqual(@string, vm.MyStringProperty); 75 | Assert.AreEqual(dateTime, vm.MyDateTimeProperty); 76 | Assert.AreEqual(providedName, vm.MyObjectProperty); 77 | Assert.AreEqual(@string, vm.MyFuncStringProperty()); 78 | Assert.AreEqual(strings, vm.MyListStringProperty); 79 | 80 | // Fields 81 | Assert.AreEqual(boolean, vm.MyBooleanField); 82 | Assert.AreEqual(integer, vm.MyIntegerField); 83 | Assert.AreEqual(@string, vm.MyStringField); 84 | Assert.AreEqual(dateTime, vm.MyDateTimeField); 85 | Assert.AreEqual(providedName, vm.MyObjectField); 86 | Assert.AreEqual(@string, vm.MyFuncStringField()); 87 | Assert.AreEqual(strings, vm.MyListStringField); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Uno.CodeGen.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461 5 | false 6 | 1701;1702;1705;NU1701 7 | Uno.CodeGen.Tests.ruleset 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | all 27 | runtime; build; native; contentfiles; analyzers 28 | 29 | 30 | NU1701 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | false 54 | true 55 | TargetFramework 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.Tests/Uno.CodeGen.Tests.ruleset: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 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 | -------------------------------------------------------------------------------- /src/Uno.CodeGen.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2024 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen", "Uno.CodeGen\Uno.CodeGen.csproj", "{7A05DD54-F3F1-4A48-97A5-1A5F45D9F315}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen.Tests", "Uno.CodeGen.Tests\Uno.CodeGen.Tests.csproj", "{AB977C38-BF77-42E2-A10C-335C261E0E03}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315} = {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315} 11 | EndProjectSection 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Immutables", "Uno.Immutables\Uno.Immutables.csproj", "{6D6DD983-D919-4CE0-88FC-26FBF34FC763}" 14 | EndProject 15 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Equality", "Uno.Equality\Uno.Equality.csproj", "{0F785D54-1A9B-4B3A-AEB2-B40FE8C81577}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Doc", "Doc", "{0C1D81C9-BE02-4D97-999D-D2079A5F8CDA}" 18 | ProjectSection(SolutionItems) = preProject 19 | ..\doc\Class Lifecycle Generation.md = ..\doc\Class Lifecycle Generation.md 20 | ..\doc\Equality Generation.md = ..\doc\Equality Generation.md 21 | ..\doc\Immutable Generation.md = ..\doc\Immutable Generation.md 22 | ..\doc\Injectable Generation.md = ..\doc\Injectable Generation.md 23 | ..\readme.md = ..\readme.md 24 | EndProjectSection 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.ClassLifecycle", "Uno.ClassLifecycle\Uno.ClassLifecycle.csproj", "{00249E44-CF67-4358-AB2C-D55AF528DAC0}" 27 | EndProject 28 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen.ClassLifecycle", "Uno.CodeGen.ClassLifecycle\Uno.CodeGen.ClassLifecycle.csproj", "{3F7D2A75-2FBE-4B2C-AB93-1FBF7EFFE3C9}" 29 | EndProject 30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen.Tests.ExternalClasses", "Uno.CodeGen.Tests.ExternalClasses\Uno.CodeGen.Tests.ExternalClasses.csproj", "{907C30BD-0984-4D75-8A43-107C98235F65}" 31 | EndProject 32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.Injectable", "Uno.Injectable\Uno.Injectable.csproj", "{5D545289-1318-428E-8ED9-5D5BA9BFE244}" 33 | EndProject 34 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen.Tests.MinimalDeps", "Uno.CodeGen.Tests.MinimalDeps\Uno.CodeGen.Tests.MinimalDeps.csproj", "{36B61385-CE6D-4493-8AFF-F77F1E4F7CFA}" 35 | EndProject 36 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Uno.CodeGen.Tests.JsonDisabled", "Uno.CodeGen.Tests.JsonDisabled\Uno.CodeGen.Tests.JsonDisabled.csproj", "{8A1F7BE0-46F6-455B-8720-5B0698843733}" 37 | EndProject 38 | Global 39 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 40 | Debug|Any CPU = Debug|Any CPU 41 | Release|Any CPU = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 44 | {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {7A05DD54-F3F1-4A48-97A5-1A5F45D9F315}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {AB977C38-BF77-42E2-A10C-335C261E0E03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {AB977C38-BF77-42E2-A10C-335C261E0E03}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {AB977C38-BF77-42E2-A10C-335C261E0E03}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {AB977C38-BF77-42E2-A10C-335C261E0E03}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {6D6DD983-D919-4CE0-88FC-26FBF34FC763}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {6D6DD983-D919-4CE0-88FC-26FBF34FC763}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {6D6DD983-D919-4CE0-88FC-26FBF34FC763}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {6D6DD983-D919-4CE0-88FC-26FBF34FC763}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {0F785D54-1A9B-4B3A-AEB2-B40FE8C81577}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {0F785D54-1A9B-4B3A-AEB2-B40FE8C81577}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {0F785D54-1A9B-4B3A-AEB2-B40FE8C81577}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {0F785D54-1A9B-4B3A-AEB2-B40FE8C81577}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {00249E44-CF67-4358-AB2C-D55AF528DAC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {00249E44-CF67-4358-AB2C-D55AF528DAC0}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {00249E44-CF67-4358-AB2C-D55AF528DAC0}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {00249E44-CF67-4358-AB2C-D55AF528DAC0}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {3F7D2A75-2FBE-4B2C-AB93-1FBF7EFFE3C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {3F7D2A75-2FBE-4B2C-AB93-1FBF7EFFE3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {3F7D2A75-2FBE-4B2C-AB93-1FBF7EFFE3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {3F7D2A75-2FBE-4B2C-AB93-1FBF7EFFE3C9}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {907C30BD-0984-4D75-8A43-107C98235F65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {907C30BD-0984-4D75-8A43-107C98235F65}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {907C30BD-0984-4D75-8A43-107C98235F65}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {907C30BD-0984-4D75-8A43-107C98235F65}.Release|Any CPU.Build.0 = Release|Any CPU 72 | {5D545289-1318-428E-8ED9-5D5BA9BFE244}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {5D545289-1318-428E-8ED9-5D5BA9BFE244}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {5D545289-1318-428E-8ED9-5D5BA9BFE244}.Release|Any CPU.ActiveCfg = Release|Any CPU 75 | {5D545289-1318-428E-8ED9-5D5BA9BFE244}.Release|Any CPU.Build.0 = Release|Any CPU 76 | {36B61385-CE6D-4493-8AFF-F77F1E4F7CFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 77 | {36B61385-CE6D-4493-8AFF-F77F1E4F7CFA}.Debug|Any CPU.Build.0 = Debug|Any CPU 78 | {36B61385-CE6D-4493-8AFF-F77F1E4F7CFA}.Release|Any CPU.ActiveCfg = Release|Any CPU 79 | {36B61385-CE6D-4493-8AFF-F77F1E4F7CFA}.Release|Any CPU.Build.0 = Release|Any CPU 80 | {8A1F7BE0-46F6-455B-8720-5B0698843733}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 81 | {8A1F7BE0-46F6-455B-8720-5B0698843733}.Debug|Any CPU.Build.0 = Debug|Any CPU 82 | {8A1F7BE0-46F6-455B-8720-5B0698843733}.Release|Any CPU.ActiveCfg = Release|Any CPU 83 | {8A1F7BE0-46F6-455B-8720-5B0698843733}.Release|Any CPU.Build.0 = Release|Any CPU 84 | EndGlobalSection 85 | GlobalSection(SolutionProperties) = preSolution 86 | HideSolutionNode = FALSE 87 | EndGlobalSection 88 | GlobalSection(ExtensibilityGlobals) = postSolution 89 | SolutionGuid = {9F663DEC-A145-475E-A087-347FF527750D} 90 | EndGlobalSection 91 | EndGlobal 92 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/CompilationReferencesListingGenerator.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Linq; 19 | using System.Text; 20 | using Uno.SourceGeneration; 21 | 22 | namespace Uno 23 | { 24 | /// 25 | /// Simple generator outputing a list of all references used to compile the project. 26 | /// 27 | /// 28 | /// Generates only one file containing only comments. 29 | /// 30 | public class CompilationReferencesListingGenerator : SourceGenerator 31 | { 32 | /// 33 | public override void Execute(SourceGeneratorContext context) 34 | { 35 | var output = new StringBuilder(); 36 | 37 | output.AppendLine("// This is the list of all external references used to compile this project:"); 38 | 39 | var lines = context 40 | .Compilation 41 | .References 42 | .OrderBy(r => r.Display, StringComparer.InvariantCultureIgnoreCase) 43 | .Select((r, i) => $"// #{i}: {r.Display}"); 44 | 45 | output.AppendLine(string.Join(Environment.NewLine, lines)); 46 | 47 | context.AddCompilationUnit(nameof(CompilationReferencesListingGenerator), output.ToString()); 48 | 49 | var projectReferences = context 50 | .GetProjectInstance() 51 | .Items 52 | .Where(i => i.ItemType.Equals("PackageReference", StringComparison.OrdinalIgnoreCase)) 53 | .ToArray(); 54 | 55 | var projectDependencies = context 56 | .GetProjectInstance() 57 | .Items 58 | .Where(i => i.ItemType.Equals("PackageDependencies", StringComparison.OrdinalIgnoreCase)) 59 | .ToArray(); 60 | 61 | projectReferences.ToString(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/Helpers/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | using System.Diagnostics; 21 | using System.Linq; 22 | using System.Reflection; 23 | using Microsoft.CodeAnalysis; 24 | 25 | namespace Uno.Helpers 26 | { 27 | public static class StringExtensions 28 | { 29 | public static int GetStableHashCode(this string str) 30 | { 31 | // A fully managed version of the 64bit GetHashCode() that does not use any randomization and will always return 32 | // the same value for equal strings. 33 | // https://stackoverflow.com/questions/36845430/persistent-hashcode-for-strings 34 | unchecked 35 | { 36 | int hash1 = 5381; 37 | int hash2 = hash1; 38 | 39 | for (int i = 0; i < str.Length && str[i] != '\0'; i += 2) 40 | { 41 | hash1 = ((hash1 << 5) + hash1) ^ str[i]; 42 | if (i == str.Length - 1 || str[i + 1] == '\0') 43 | break; 44 | hash2 = ((hash2 << 5) + hash2) ^ str[i + 1]; 45 | } 46 | 47 | return hash1 + (hash2 * 1566083941); 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/InjectableGenerator.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | using Microsoft.CodeAnalysis; 20 | using Uno.Helpers; 21 | using Uno.RoslynHelpers; 22 | using Uno.SourceGeneration; 23 | 24 | namespace Uno 25 | { 26 | /// 27 | /// Responsible for the code generation of injectable types. 28 | /// 29 | /// 30 | /// The trigger for this generator is . 31 | /// 32 | public class InjectableGenerator : SourceGenerator 33 | { 34 | private SourceGeneratorContext _context; 35 | private INamedTypeSymbol _injectAttributeSymbol; 36 | 37 | /// 38 | public override void Execute(SourceGeneratorContext context) 39 | { 40 | _context = context; 41 | _injectAttributeSymbol = context.Compilation.GetTypeByMetadataName("Uno.InjectAttribute"); 42 | 43 | var injectables = EnumerateInjectables(); 44 | 45 | foreach (var injectable in injectables) 46 | { 47 | GenerateInjectable(injectable); 48 | } 49 | } 50 | 51 | private IEnumerable<(INamedTypeSymbol type, IEnumerable<(ISymbol member, AttributeData attribute)> attributes)> EnumerateInjectables() => 52 | from type in _context.Compilation.SourceModule.GlobalNamespace.GetNamespaceTypes() 53 | from member in Enumerable.Concat(type.GetProperties(), type.GetFields()) 54 | from attribute in member.GetAttributes() 55 | where attribute.AttributeClass == _injectAttributeSymbol 56 | group (member, attribute) by type into g 57 | select (type: g.Key, attributes: g.AsEnumerable()); 58 | 59 | private void GenerateInjectable((INamedTypeSymbol type, IEnumerable<(ISymbol member, AttributeData attribute)> attributes) injectable) 60 | { 61 | var typeNames = injectable.type.GetSymbolNames(); 62 | var (typeName, genericArguments, typeNameWithGenerics, typeNameForXml, typeNameDefinition, resultFileName, genericConstraints) = typeNames; 63 | 64 | var builder = new IndentedStringBuilder(); 65 | 66 | builder.AppendLineInvariant("// "); 67 | builder.AppendLineInvariant("// **************************************************************(********************************************************"); 68 | builder.AppendLineInvariant("// This file has been generated by Uno.CodeGen (InjectableGenerator), available at https://github.com/nventive/Uno.CodeGen"); 69 | builder.AppendLineInvariant("// ***********************************************************************************************************************"); 70 | builder.AppendLineInvariant("// "); 71 | builder.AppendLineInvariant("#pragma warning disable"); 72 | builder.AppendLine(); 73 | builder.AppendLineInvariant("using System;"); 74 | builder.AppendLine(); 75 | 76 | using (builder.BlockInvariant($"namespace {injectable.type.ContainingNamespace}")) 77 | { 78 | using (builder.BlockInvariant($"partial class {injectable.type.Name} : global::Uno.IInjectable")) 79 | { 80 | using (builder.BlockInvariant($"void global::Uno.IInjectable.Inject(global::Uno.DependencyResolver resolver)")) 81 | { 82 | foreach (var attribute in injectable.attributes) 83 | { 84 | var memberName = attribute.member.Name; 85 | var memberType = GetMemberType(attribute.member); 86 | var memberTypeName = memberType.GetSymbolNames()?.GetSymbolFullNameWithGenerics() ?? memberType?.ToDisplayString(); 87 | var name = attribute.attribute.ConstructorArguments.Select(x => x.Value?.ToString()).FirstOrDefault(); 88 | var nameLiteral = name != null ? $"\"{name}\"" : "null"; 89 | 90 | if (memberType.IsFunc(out var funcResultType)) // Resolve lazily 91 | { 92 | var funcResultTypeName = funcResultType?.GetSymbolNames()?.GetSymbolFullNameWithGenerics() ?? funcResultType?.ToDisplayString(); 93 | builder.AppendLineInvariant($"{memberName} = () => ({funcResultTypeName})resolver(typeof({funcResultTypeName}), {nameLiteral});"); 94 | } 95 | else 96 | { 97 | builder.AppendLineInvariant($"{memberName} = ({memberTypeName})resolver(typeof({memberTypeName}), {nameLiteral});"); 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | _context.AddCompilationUnit(resultFileName, builder.ToString()); 105 | } 106 | 107 | private static ITypeSymbol GetMemberType(ISymbol member) 108 | { 109 | switch (member) 110 | { 111 | case IPropertySymbol property: 112 | return property.Type; 113 | case IFieldSymbol field: 114 | return field.Type; 115 | default: 116 | return null; 117 | } 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Uno.CodeGen": { 4 | "commandName": "Executable", 5 | "executablePath": "$(DevEnvDir)..\\..\\MSBuild\\15.0\\Bin\\MSBuild.exe", 6 | "commandLineArgs": "..\\..\\..\\..\\Uno.CodeGen.Tests\\Uno.CodeGen.Tests.csproj /p:Configuration=Debug" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/Uno.CodeGen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;netstandard2.0 5 | true 6 | 1701;1702;1705;NU1701 7 | true 8 | Uno 9 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 10 | nventive 11 | nventive 12 | https://github.com/nventive/Uno.CodeGen 13 | https://nv-assets.azurewebsites.net/logos/uno.png 14 | https://github.com/nventive/Uno.CodeGen 15 | This package provides tooling for code generation. 16 | Copyright (C) 2015-$([System.DateTime]::Now.ToString(`yyyy`)) nventive inc. - all rights reserved 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | compile; build; native; contentfiles; analyzers; buildtransitive 26 | 27 | 28 | 29 | 30 | 31 | 32 | all 33 | runtime; build; native; contentfiles; analyzers 34 | 35 | 36 | NU1701 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | true 48 | build 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/Uno.CodeGen/build/Uno.CodeGen.props: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /src/Uno.Common.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | $(NoWarn);NU5048 7 | 10.0 8 | 9 | 10 | 14 | 15 | 16 | <_OverrideTargetFramework>$(TargetFramework) 17 | <_TargetNugetFolder Condition="'$(IsTool)'=='true' AND '$(TargetFramework)' == 'net461'">$(USERPROFILE)\.nuget\packages\$(AssemblyName)\$(NugetOverrideVersion)\tools 18 | <_TargetNugetFolder Condition="'$(IsTool)'!='true'">$(USERPROFILE)\.nuget\packages\$(AssemblyName)\$(NugetOverrideVersion)\lib\$(_OverrideTargetFramework) 19 | 20 | 21 | <_OutputFiles Include="@(BuiltProjectOutputGroupOutput)" /> 22 | <_OutputFilesPDB Include="@(_OutputFiles->'%(RootDir)\%(Directory)\%(RecursiveDir)%(Filename).pdb')" Condition="Exists('@(BuiltProjectOutputGroupOutput->'%(RootDir)\%(Directory)\%(RecursiveDir)%(Filename).pdb')')" /> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 34 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/Uno.Equality/CollectionComparerMode.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.Equality 18 | { 19 | /// 20 | /// Use to qualify the collection mode in attribute. 21 | /// 22 | public enum CollectionComparerMode : int 23 | { 24 | /// 25 | /// No special mode for comparer 26 | /// 27 | Default = 0, 28 | 29 | /// 30 | /// Use a comparer which allows for a different ordering between collections. 31 | /// 32 | /// 33 | /// This is not a flag, the flag is on `Sorted` 34 | /// 35 | Unsorted = 0b0000, 36 | 37 | /// 38 | /// Use a comparer which checks the ordering in the collections. 39 | /// 40 | Sorted = 0b0001, 41 | 42 | /// 43 | /// Treat null collection and empty ones are equals. 44 | /// 45 | NullIsEmpty = 0b0010, 46 | } 47 | } -------------------------------------------------------------------------------- /src/Uno.Equality/DictionaryEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace Uno.Equality 21 | { 22 | /// 23 | /// implementation for evaluating dictionaries 24 | /// 25 | public class DictionaryEqualityComparer : IEqualityComparer 26 | where TDict : IDictionary 27 | { 28 | private readonly bool _nullIsEmpty; 29 | private readonly IEqualityComparer _valueComparer; 30 | 31 | /// 32 | /// Default instance of the comparer with a default equality comparer for values. 33 | /// 34 | public static IEqualityComparer Default { get; } = new DictionaryEqualityComparer(); 35 | 36 | /// 37 | /// ctor 38 | /// 39 | /// Comparer to use to comparer an enumerated item 40 | /// If null value should be compated as empty collection 41 | public DictionaryEqualityComparer(IEqualityComparer valueComparer = null, bool nullIsEmpty = true) 42 | { 43 | _nullIsEmpty = nullIsEmpty; 44 | _valueComparer = valueComparer ?? EqualityComparer.Default; 45 | } 46 | 47 | /// 48 | public bool Equals(TDict x, TDict y) 49 | { 50 | return (Equals(x, y, _valueComparer, _nullIsEmpty)); 51 | } 52 | 53 | /// 54 | /// Static (instance-less) equality check 55 | /// 56 | public static bool Equals(TDict x, TDict y, IEqualityComparer valueComparer, bool nullIsEmpty = true) 57 | { 58 | if (valueComparer == null) 59 | { 60 | throw new ArgumentNullException(nameof(valueComparer)); 61 | } 62 | 63 | if (nullIsEmpty) 64 | { 65 | if (x == null) 66 | { 67 | return y == null || y.Count == 0; 68 | } 69 | 70 | if (y == null) 71 | { 72 | return x.Count == 0; 73 | } 74 | } 75 | else 76 | { 77 | if (x == null) 78 | { 79 | return y == null; 80 | } 81 | 82 | if (y == null) 83 | { 84 | return false; 85 | } 86 | } 87 | 88 | if (x.Count != y.Count) 89 | { 90 | return false; 91 | } 92 | 93 | foreach (var keyValue in x) 94 | { 95 | if (!y.TryGetValue(keyValue.Key, out var yValue)) 96 | { 97 | return false; // key not found: dictionaries are not equal. 98 | } 99 | 100 | if (!valueComparer.Equals(keyValue.Value, yValue)) 101 | { 102 | return false; // value for this key is different. 103 | } 104 | } 105 | 106 | return true; // no differences found 107 | } 108 | 109 | /// 110 | public int GetHashCode(TDict obj) 111 | { 112 | return obj?.Count ?? 0; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Uno.Equality/EqualityComparerOptionsAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno.Equality 20 | { 21 | /// 22 | /// Attribute to put on a collection field/property to specify the kind 23 | /// of collection comparer to use. 24 | /// 25 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 26 | public class EqualityComparerOptionsAttribute : Attribute 27 | { 28 | /// 29 | /// Specify a special mode when it's a collection. 30 | /// 31 | /// 32 | /// No effect on non-collection fields/properties 33 | /// 34 | public CollectionComparerMode CollectionMode { get; set; } = CollectionComparerMode.Default; 35 | 36 | /// 37 | /// Specify a special mode when it's a string. 38 | /// 39 | /// 40 | /// No effect on non-string fields/properties 41 | /// 42 | public StringComparerMode StringMode { get; set; } = StringComparerMode.Default; 43 | } 44 | } -------------------------------------------------------------------------------- /src/Uno.Equality/EqualityHashAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Define a field/property to use for generating the method. 23 | /// 24 | /// 25 | /// Use in conjonction with . 26 | /// * If this attribute is not used, you must manually define a attribute 27 | /// * You can put this attribute to more than one member of your class. They will all be used for HashCode calculation. 28 | /// 29 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 30 | public class EqualityHashAttribute : Attribute 31 | { 32 | } 33 | } -------------------------------------------------------------------------------- /src/Uno.Equality/EqualityIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Don't use this field/property for equality generation 23 | /// 24 | /// 25 | /// Can be placed on a member (field or property) or on a type (class/struct). 26 | /// When placed on a type, means this value will never be used for equality generation. 27 | /// 28 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)] 29 | public class EqualityIgnoreAttribute : Attribute 30 | { 31 | } 32 | } -------------------------------------------------------------------------------- /src/Uno.Equality/EqualityKeyAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using Uno.Equality; 19 | 20 | namespace Uno 21 | { 22 | /// 23 | /// Define a field/property to use for generating the method. 24 | /// 25 | /// 26 | /// Use in conjonction with . 27 | /// * If this attribute is not used, you must manually define a attribute 28 | /// * You can put this attribute to more than one member of your class. They will all be used for HashCode calculation. 29 | /// 30 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 31 | public class EqualityKeyAttribute : Attribute 32 | { 33 | /// 34 | /// Override for equality mode 35 | /// 36 | public KeyEqualityMode Mode { get; } 37 | 38 | /// 39 | public EqualityKeyAttribute(KeyEqualityMode mode = KeyEqualityMode.Auto) 40 | { 41 | Mode = mode; 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Uno.Equality/GeneratedEqualityAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Instruct the source code generator to operate on this target class (or struct) 23 | /// to generate equality members. 24 | /// 25 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true, AllowMultiple = false)] 26 | public class GeneratedEqualityAttribute : Attribute 27 | { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Uno.Equality/KeyEqualityMode.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno.Equality 18 | { 19 | /// 20 | /// Mode to use for 21 | /// 22 | public enum KeyEqualityMode 23 | { 24 | /// 25 | /// Will use the KeyEquality if found on type, fallback to normal equality 26 | /// 27 | /// 28 | /// This is the default mode. 29 | /// 30 | Auto, 31 | 32 | /// 33 | /// Delegate the key equality to the _KeyEquality_ of the member type 34 | /// 35 | /// 36 | /// Will fail if type is not implementing KeyEquality. If you're not sure 37 | /// which you want, use `Auto`. 38 | /// 39 | UseKeyEquality, 40 | 41 | /// 42 | /// Delegate the key equality to the _Equality_ of the member type. 43 | /// 44 | UseEquality 45 | } 46 | } -------------------------------------------------------------------------------- /src/Uno.Equality/ReadonlyDictionaryEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | 20 | namespace Uno.Equality 21 | { 22 | /// 23 | /// implementation for evaluating dictionaries 24 | /// 25 | public class ReadonlyDictionaryEqualityComparer : IEqualityComparer 26 | where TDict : IReadOnlyDictionary 27 | { 28 | private readonly bool _nullIsEmpty; 29 | private readonly IEqualityComparer _valueComparer; 30 | 31 | /// 32 | /// Default instance of the comparer with a default equality comparer for values. 33 | /// 34 | public static IEqualityComparer Default { get; } = new ReadonlyDictionaryEqualityComparer(); 35 | 36 | /// 37 | /// ctor 38 | /// 39 | /// Comparer to use to comparer an enumerated item 40 | /// If null value should be compated as empty collection 41 | public ReadonlyDictionaryEqualityComparer(IEqualityComparer valueComparer = null, bool nullIsEmpty = true) 42 | { 43 | _nullIsEmpty = nullIsEmpty; 44 | _valueComparer = valueComparer ?? EqualityComparer.Default; 45 | } 46 | 47 | /// 48 | public bool Equals(TDict x, TDict y) 49 | { 50 | return (Equals(x, y, _valueComparer, _nullIsEmpty)); 51 | } 52 | 53 | /// 54 | /// Static (instance-less) equality check 55 | /// 56 | public static bool Equals(TDict x, TDict y, IEqualityComparer valueComparer, bool nullIsEmpty = true) 57 | { 58 | if (valueComparer == null) 59 | { 60 | throw new ArgumentNullException(nameof(valueComparer)); 61 | } 62 | 63 | if (nullIsEmpty) 64 | { 65 | if (x == null) 66 | { 67 | return y == null || y.Count == 0; 68 | } 69 | 70 | if (y == null) 71 | { 72 | return x.Count == 0; 73 | } 74 | } 75 | else 76 | { 77 | if (x == null) 78 | { 79 | return y == null; 80 | } 81 | 82 | if (y == null) 83 | { 84 | return false; 85 | } 86 | } 87 | 88 | if (x.Count != y.Count) 89 | { 90 | return false; 91 | } 92 | 93 | foreach (var keyValue in x) 94 | { 95 | if (!y.TryGetValue(keyValue.Key, out var yValue)) 96 | { 97 | return false; // key not found: dictionaries are not equal. 98 | } 99 | 100 | if (!valueComparer.Equals(keyValue.Value, yValue)) 101 | { 102 | return false; // value for this key is different. 103 | } 104 | } 105 | 106 | return true; // no difference found 107 | } 108 | 109 | /// 110 | public int GetHashCode(TDict obj) 111 | { 112 | return obj?.Count ?? 0; 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /src/Uno.Equality/SortedCollectionEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | 21 | namespace Uno.Equality 22 | { 23 | /// 24 | /// implementation for evaluating sorted collections 25 | /// 26 | public class SortedCollectionEqualityComparer : IEqualityComparer 27 | where TCollection : ICollection 28 | { 29 | private readonly IEqualityComparer _itemComparer; 30 | private readonly bool _nullIsEmpty; 31 | 32 | /// 33 | /// Default instance of the comparer with a default equality comparer for items. 34 | /// 35 | public static IEqualityComparer Default { get; } = new SortedCollectionEqualityComparer(); 36 | 37 | /// 38 | /// ctor 39 | /// 40 | /// Comparer to use to comparer an enumerated item 41 | /// If null value should be compated as empty collection 42 | public SortedCollectionEqualityComparer(IEqualityComparer itemComparer = null, bool nullIsEmpty = true) 43 | { 44 | _itemComparer = itemComparer ?? EqualityComparer.Default; 45 | _nullIsEmpty = nullIsEmpty; 46 | } 47 | 48 | /// 49 | public bool Equals(TCollection x, TCollection y) 50 | { 51 | return(Equals(x, y, _itemComparer, _nullIsEmpty)); 52 | } 53 | 54 | /// 55 | /// Static (instance-less) equality check 56 | /// 57 | public static bool Equals(TCollection x, TCollection y, IEqualityComparer itemComparer, bool nullIsEmpty = true) 58 | { 59 | if (itemComparer == null) 60 | { 61 | throw new ArgumentNullException(nameof(itemComparer)); 62 | } 63 | 64 | if (nullIsEmpty) 65 | { 66 | if (x == null) 67 | { 68 | return y == null || y.Count == 0; 69 | } 70 | 71 | if (y == null) 72 | { 73 | return x.Count == 0; 74 | } 75 | } 76 | else 77 | { 78 | if (x == null) 79 | { 80 | return y == null; 81 | } 82 | 83 | if (y == null) 84 | { 85 | return false; 86 | } 87 | } 88 | 89 | if (x.Count != y.Count) 90 | { 91 | return false; 92 | } 93 | 94 | var sequenceEqual = x.SequenceEqual(y, itemComparer); 95 | return sequenceEqual; 96 | } 97 | 98 | /// 99 | public int GetHashCode(TCollection obj) 100 | { 101 | return obj?.Count ?? 0; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/Uno.Equality/SortedReadonlyCollectionEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | 21 | namespace Uno.Equality 22 | { 23 | /// 24 | /// implementation for evaluating sorted collections 25 | /// 26 | public class SortedReadonlyCollectionEqualityComparer : IEqualityComparer 27 | where TCollection : IReadOnlyCollection 28 | { 29 | private readonly IEqualityComparer _itemComparer; 30 | private readonly bool _nullIsEmpty; 31 | 32 | /// 33 | /// Default instance of the comparer with a default equality comparer for items. 34 | /// 35 | public static IEqualityComparer Default { get; } = new SortedReadonlyCollectionEqualityComparer(); 36 | 37 | /// 38 | /// ctor 39 | /// 40 | /// Comparer to use to comparer an enumerated item 41 | /// If null value should be compated as empty collection 42 | public SortedReadonlyCollectionEqualityComparer(IEqualityComparer itemComparer = null, bool nullIsEmpty = true) 43 | { 44 | _itemComparer = itemComparer ?? EqualityComparer.Default; 45 | _nullIsEmpty = nullIsEmpty; 46 | } 47 | 48 | /// 49 | public bool Equals(TCollection x, TCollection y) 50 | { 51 | return (Equals(x, y, _itemComparer, _nullIsEmpty)); 52 | } 53 | 54 | /// 55 | /// Static (instance-less) equality check 56 | /// 57 | public static bool Equals(TCollection x, TCollection y, IEqualityComparer itemComparer, bool nullIsEmpty = true) 58 | { 59 | if (itemComparer == null) 60 | { 61 | throw new ArgumentNullException(nameof(itemComparer)); 62 | } 63 | 64 | if (nullIsEmpty) 65 | { 66 | if (x == null) 67 | { 68 | return y == null || y.Count == 0; 69 | } 70 | 71 | if (y == null) 72 | { 73 | return x.Count == 0; 74 | } 75 | } 76 | else 77 | { 78 | if (x == null) 79 | { 80 | return y == null; 81 | } 82 | 83 | if (y == null) 84 | { 85 | return false; 86 | } 87 | } 88 | 89 | if (x.Count != y.Count) 90 | { 91 | return false; 92 | } 93 | 94 | var sequenceEqual = x.SequenceEqual(y, itemComparer); 95 | return sequenceEqual; 96 | } 97 | 98 | /// 99 | public int GetHashCode(TCollection obj) 100 | { 101 | return obj?.Count ?? 0; 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /src/Uno.Equality/StringComparerMode.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno.Equality 20 | { 21 | /// 22 | /// Use to qualify the string mode in attribute. 23 | /// 24 | [Flags] 25 | public enum StringComparerMode : byte 26 | { 27 | /// 28 | /// No modes activated 29 | /// 30 | Default = 0, 31 | 32 | /// 33 | /// Ignore casing when comparing 34 | /// 35 | IgnoreCase = 0b0001, 36 | 37 | /// 38 | /// Treat empty/white strings and null as equal 39 | /// 40 | EmptyEqualsNull = 0b0010, 41 | } 42 | } -------------------------------------------------------------------------------- /src/Uno.Equality/Uno.Equality.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netstandard1.3;netstandard2.0 5 | Equality Declarations 6 | true 7 | True 8 | 9 | full 10 | True 11 | nventive 12 | nventive 13 | This package provides attributes for Equality source code generation. 14 | This package is part of the Uno.CodeGen to generate equality members in your project. 15 | Uno.Equality 16 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 17 | Copyright (C) 2015-2018 nventive inc. - all rights reserved 18 | https://github.com/nventive/Uno.CodeGen 19 | https://github.com/nventive/Uno.CodeGen 20 | https://nv-assets.azurewebsites.net/logos/uno.png 21 | 22 | 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Uno.Equality/UnsortedCollectionEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | 21 | namespace Uno.Equality 22 | { 23 | /// 24 | /// implementation for evaluating unsorted collections 25 | /// 26 | /// 27 | /// Will produce weird result on collection with repeated items (should be a "Set") 28 | /// 29 | public class UnsortedCollectionEqualityComparer : IEqualityComparer 30 | where TCollection : ICollection 31 | { 32 | private readonly IEqualityComparer _itemComparer; 33 | private readonly bool _nullIsEmpty; 34 | 35 | /// 36 | /// Default instance of the comparer with a default equality comparer for items. 37 | /// 38 | public static IEqualityComparer Default { get; } = new UnsortedCollectionEqualityComparer(); 39 | 40 | /// 41 | /// ctor 42 | /// 43 | /// Comparer to use to comparer an enumerated item 44 | /// If null value should be compated as empty collection 45 | public UnsortedCollectionEqualityComparer(IEqualityComparer itemComparer = null, bool nullIsEmpty = true) 46 | { 47 | _itemComparer = itemComparer ?? EqualityComparer.Default; 48 | _nullIsEmpty = nullIsEmpty; 49 | } 50 | 51 | /// 52 | public bool Equals(TCollection x, TCollection y) 53 | { 54 | return (Equals(x, y, _itemComparer, _nullIsEmpty)); 55 | } 56 | 57 | /// 58 | /// Static (instance-less) equality check 59 | /// 60 | public static bool Equals(TCollection x, TCollection y, IEqualityComparer itemComparer, bool nullIsEmpty = true) 61 | { 62 | if (itemComparer == null) 63 | { 64 | throw new ArgumentNullException(nameof(itemComparer)); 65 | } 66 | 67 | if (nullIsEmpty) 68 | { 69 | if (x == null) 70 | { 71 | return y == null || y.Count == 0; 72 | } 73 | 74 | if (y == null) 75 | { 76 | return x.Count == 0; 77 | } 78 | } 79 | else 80 | { 81 | if (x == null) 82 | { 83 | return y == null; 84 | } 85 | 86 | if (y == null) 87 | { 88 | return false; 89 | } 90 | } 91 | 92 | if (x.Count != y.Count) 93 | { 94 | return false; 95 | } 96 | 97 | return x.All(item => y.Contains(item, itemComparer)); 98 | } 99 | 100 | /// 101 | public int GetHashCode(TCollection obj) 102 | { 103 | return obj?.Count ?? 0; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/Uno.Equality/UnsortedReadonlyCollectionEqualityComparer.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | 21 | namespace Uno.Equality 22 | { 23 | /// 24 | /// implementation for evaluating unsorted collections 25 | /// 26 | /// 27 | /// Will produce weird result on collection with repeated items (should be a "Set") 28 | /// 29 | public class UnsortedReadonlyCollectionEqualityComparer : IEqualityComparer 30 | where TCollection : IReadOnlyCollection 31 | { 32 | private readonly IEqualityComparer _itemComparer; 33 | private readonly bool _nullIsEmpty; 34 | 35 | /// 36 | /// Default instance of the comparer with a default equality comparer for items. 37 | /// 38 | public static IEqualityComparer Default { get; } = new UnsortedReadonlyCollectionEqualityComparer(); 39 | 40 | /// 41 | /// ctor 42 | /// 43 | /// Comparer to use to comparer an enumerated item 44 | /// If null value should be compated as empty collection 45 | public UnsortedReadonlyCollectionEqualityComparer(IEqualityComparer itemComparer = null, bool nullIsEmpty = true) 46 | { 47 | _itemComparer = itemComparer ?? EqualityComparer.Default; 48 | _nullIsEmpty = nullIsEmpty; 49 | } 50 | 51 | /// 52 | public bool Equals(TCollection x, TCollection y) 53 | { 54 | return (Equals(x, y, _itemComparer, _nullIsEmpty)); 55 | } 56 | 57 | /// 58 | /// Static (instance-less) equality check 59 | /// 60 | public static bool Equals(TCollection x, TCollection y, IEqualityComparer itemComparer, bool nullIsEmpty = true) 61 | { 62 | if (itemComparer == null) 63 | { 64 | throw new ArgumentNullException(nameof(itemComparer)); 65 | } 66 | 67 | if (nullIsEmpty) 68 | { 69 | if (x == null) 70 | { 71 | return y == null || y.Count == 0; 72 | } 73 | 74 | if (y == null) 75 | { 76 | return x.Count == 0; 77 | } 78 | } 79 | else 80 | { 81 | if (x == null) 82 | { 83 | return y == null; 84 | } 85 | 86 | if (y == null) 87 | { 88 | return false; 89 | } 90 | } 91 | 92 | if (x.Count != y.Count) 93 | { 94 | return false; 95 | } 96 | 97 | return x.All(item => y.Contains(item, itemComparer)); 98 | } 99 | 100 | /// 101 | public int GetHashCode(TCollection obj) 102 | { 103 | return obj?.Count ?? 0; 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /src/Uno.Immutables/GeneratedImmutableAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Indicates the code-gen to generate immutability builders for the target class 23 | /// 24 | [System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 25 | public sealed class GeneratedImmutableAttribute : Attribute 26 | { 27 | /// 28 | /// If the generation code for Equality should be generated at the same time. 29 | /// 30 | public bool GenerateEquality { get; set; } = false; 31 | } 32 | } -------------------------------------------------------------------------------- /src/Uno.Immutables/IImmutableBuilder.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | namespace Uno 18 | { 19 | /// 20 | /// Represents the builder of an immutable type. 21 | /// 22 | public interface IImmutableBuilder 23 | { 24 | /// 25 | /// Get an immutable version from the current state of the mutable object. 26 | /// 27 | #if !NETSTANDARD1_3 28 | [System.Diagnostics.Contracts.Pure] 29 | #endif 30 | TImmutable ToImmutable(); 31 | } 32 | } -------------------------------------------------------------------------------- /src/Uno.Immutables/ImmutableAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Text; 20 | 21 | namespace Uno 22 | { 23 | /// 24 | /// Indicates that the attributed class is immutable. 25 | /// 26 | /// 27 | /// This attribute is meant to be used by Roslyn analyzers to validate for immutability. 28 | /// 29 | [System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 30 | public sealed class ImmutableAttribute : Attribute 31 | { 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Uno.Immutables/ImmutableAttributeCopyIgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Defines which attributes to ignore when copying to builder 23 | /// 24 | /// 25 | /// Can be put on an assembly, a type or a property. 26 | /// 27 | [System.AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Property, Inherited = true, AllowMultiple = false)] 28 | public sealed class ImmutableAttributeCopyIgnoreAttribute : Attribute 29 | { 30 | /// 31 | /// Regex use to match the name (fullname) of the attribute type(s) to ignore. 32 | /// 33 | public string AttributeToIgnoreRegex { get; } 34 | 35 | /// 36 | public ImmutableAttributeCopyIgnoreAttribute(string attributeToIgnoreRegex) 37 | { 38 | AttributeToIgnoreRegex = attributeToIgnoreRegex; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/Uno.Immutables/ImmutableBuilderAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Indicates the type of the builder for this class. 23 | /// The type must implement 24 | /// 25 | /// 26 | /// This attribute is added on generated code and is also used by some code generators 27 | /// to find the builder to use for creating the entity. 28 | /// 29 | [System.AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)] 30 | public sealed class ImmutableBuilderAttribute : Attribute 31 | { 32 | /// 33 | /// Type to use to build this entity. 34 | /// 35 | /// 36 | /// The type must implement . 37 | /// 38 | public Type BuilderType { get; } 39 | 40 | /// 41 | public ImmutableBuilderAttribute(Type builderType) 42 | { 43 | BuilderType = builderType; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Uno.Immutables/ImmutableGenerationOptionsAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Global settings for [GenerateImmutable] generator. 23 | /// 24 | [System.AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] 25 | public sealed class ImmutableGenerationOptionsAttribute : Attribute 26 | { 27 | /// 28 | /// If you want arrays to be treat as immutable in the validation. 29 | /// 30 | /// 31 | /// Recommendation is to set this to false if you want actually immutable entities. 32 | /// 33 | public bool TreatArrayAsImmutable { get; set; } = false; 34 | 35 | /// 36 | /// If you want to generate `Option`-specific Code 37 | /// 38 | /// 39 | /// No effect if not using `Uno.Core`. 40 | /// Default to true. 41 | /// 42 | public bool GenerateOptionCode { get; set; } = true; 43 | 44 | /// 45 | /// If you want to generate equality by default. 46 | /// 47 | /// 48 | /// Default is true. Can be overridden by type on the attribute declaration 49 | /// `[GenerateImmutable(GenerateEquality=false)]` 50 | /// 51 | public bool GenerateEqualityByDefault { get; set; } = true; 52 | 53 | /// 54 | /// If you want to generate Newtownsoft's JSON.NET converters by default. 55 | /// 56 | /// 57 | /// Default is true. No effect if package `Newtownsoft.Json` is not referenced. 58 | /// 59 | public bool GenerateNewtownsoftJsonNetConverters { get; set; } = true; 60 | 61 | /// 62 | /// If you want to generate System.Text.Json converters by default. 63 | /// 64 | /// 65 | /// Default is true. No effect if package `System.Text.Json` is not referenced. 66 | /// 67 | public bool GenerateSystemTextJsonConverters { get; set; } = true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Uno.Immutables/TreatAsImmutableAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Define a type (usually external) as immutable 23 | /// 24 | [System.AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] 25 | public sealed class TreatAsImmutableAttribute : Attribute 26 | { 27 | /// 28 | /// The type known to be immutable 29 | /// 30 | public Type Type { get; } 31 | 32 | /// 33 | /// .ctor 34 | /// 35 | /// 36 | public TreatAsImmutableAttribute(Type type) 37 | { 38 | Type = type; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Uno.Immutables/Uno.Immutables.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netstandard1.3;netstandard2.0 5 | Immutable Declarations 6 | true 7 | True 8 | 9 | full 10 | True 11 | nventive 12 | nventive 13 | This package provides attributes for immutable entities source code generation. 14 | This package is part of the Uno.CodeGen to generate immutable entities in your project. 15 | Uno 16 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 17 | https://github.com/nventive/Uno.CodeGen 18 | https://github.com/nventive/Uno.CodeGen 19 | https://nv-assets.azurewebsites.net/logos/uno.png 20 | Copyright (C) 2015-2018 nventive inc. - all rights reserved 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | all 29 | runtime; build; native; contentfiles; analyzers 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/Uno.Injectable/DependencyResolver.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using System.Threading.Tasks; 22 | 23 | namespace Uno 24 | { 25 | /// 26 | /// Encapsulates a method that that resolves an dependency given its type and optional name. 27 | /// 28 | /// The type of the dependency. 29 | /// The optional name of the dependency. 30 | /// 31 | public delegate object DependencyResolver(Type type, string name = null); 32 | } -------------------------------------------------------------------------------- /src/Uno.Injectable/IInjectable.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Exposes a way to inject a dependency resolver. 23 | /// 24 | /// 25 | /// A partial class implementing is generated for every class defining properties or fields attributed with . 26 | /// 27 | public interface IInjectable 28 | { 29 | /// 30 | /// Inject the dependency resolver used to populate properties and fields attributed with . 31 | /// 32 | /// 33 | /// You are responsible for calling this method and provide the appropriate dependency resolver. 34 | /// 35 | /// The dependency resolver. 36 | void Inject(DependencyResolver resolver); 37 | } 38 | } -------------------------------------------------------------------------------- /src/Uno.Injectable/InjectAttribute.cs: -------------------------------------------------------------------------------- 1 | // ****************************************************************** 2 | // Copyright � 2015-2018 nventive inc. All rights reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // ****************************************************************** 17 | using System; 18 | 19 | namespace Uno 20 | { 21 | /// 22 | /// Indicates that the attributed property or field should be injected. 23 | /// 24 | /// 25 | /// For partial class implementing is generated for every class that defines properties or fields attributed with . 26 | /// 27 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] 28 | public sealed class InjectAttribute : Attribute 29 | { 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// The optional name used to resolve the injected instance. 34 | public InjectAttribute(string name = null) 35 | { 36 | Name = name; 37 | } 38 | 39 | /// 40 | /// The optional name used to resolve the injected instance. 41 | /// 42 | public string Name { get; } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Uno.Injectable/Uno.Injectable.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net461;netstandard1.3;netstandard2.0 5 | Injectable Declarations 6 | true 7 | True 8 | 9 | full 10 | True 11 | nventive 12 | nventive 13 | This package provides attributes for injectable entities source code generation. 14 | This package is part of the Uno.CodeGen to generate injectable entities in your project. 15 | Uno 16 | bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 17 | https://github.com/nventive/Uno.CodeGen 18 | https://github.com/nventive/Uno.CodeGen 19 | https://nv-assets.azurewebsites.net/logos/uno.png 20 | Copyright (C) 2015-2018 nventive inc. - all rights reserved 21 | 22 | 23 | 24 | 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/crosstargeting_override.props.sample: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 17 | 18 | 19 | 20 | --------------------------------------------------------------------------------