{"id":28612816,"url":"https://github.com/unoplatform/uno.sourcegeneration","last_synced_at":"2025-06-12T00:39:52.376Z","repository":{"id":35008496,"uuid":"117250427","full_name":"unoplatform/Uno.SourceGeneration","owner":"unoplatform","description":"A Roslyn based C# source generation framework","archived":false,"fork":false,"pushed_at":"2025-05-26T16:14:12.000Z","size":13868,"stargazers_count":130,"open_issues_count":12,"forks_count":11,"subscribers_count":36,"default_branch":"master","last_synced_at":"2025-06-05T22:10:03.516Z","etag":null,"topics":["csharp","generator","msbuild","roslyn","visual-studio"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unoplatform.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"License.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-01-12T14:28:27.000Z","updated_at":"2025-05-26T16:13:52.000Z","dependencies_parsed_at":"2024-01-28T20:49:34.391Z","dependency_job_id":"264f0e31-c11f-4533-8cb1-29da5a8a0aa0","html_url":"https://github.com/unoplatform/Uno.SourceGeneration","commit_stats":{"total_commits":260,"total_committers":12,"mean_commits":"21.666666666666668","dds":0.2730769230769231,"last_synced_commit":"77cea5f3a108672d2c875a38dfed9408c7d5d1df"},"previous_names":["nventive/uno.sourcegeneration"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/unoplatform/Uno.SourceGeneration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unoplatform%2FUno.SourceGeneration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unoplatform%2FUno.SourceGeneration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unoplatform%2FUno.SourceGeneration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unoplatform%2FUno.SourceGeneration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unoplatform","download_url":"https://codeload.github.com/unoplatform/Uno.SourceGeneration/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unoplatform%2FUno.SourceGeneration/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259372669,"owners_count":22847792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","generator","msbuild","roslyn","visual-studio"],"created_at":"2025-06-12T00:39:51.613Z","updated_at":"2025-06-12T00:39:52.349Z","avatar_url":"https://github.com/unoplatform.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Uno SourceGenerator\n\nThe Uno source generator is an API compatible source generator inspired\nby [Roslyn v2.0 source generation feature](https://github.com/dotnet/roslyn/blob/12bd769ebcd3121b88f535e8559f5a42d9c0e873/docs/features/generators.md), and an\nmsbuild task which executes the SourceGenerators.\n\nIt provides a way to generate C# source code based on a project being built, using all of its syntactic and semantic model information.\n\nThe Uno Source Generator also supports the [Roslyn 3.8 (C# 9.0) Source Generator APIs](https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.cookbook.md), see below for more details. Note that as of Roslyn 3.8, generators do not support multi-pass generation where generators can depend on each others. In order to benefit from this feature, a generator must run using Uno.SourceGenerationTasks.\n\nUsing this generator allows for a set of generators to share the same Roslyn compilation context, which is particularly expensive to create, and run all the generators in parallel.\n\nThe `Uno.SourceGeneratorTasks` support updating generators on the fly, making iterative development easier as visual studio or MSBuild will not lock the generator's assemblies.\n\nThe `Uno.SourceGeneratorTasks` support any target framework for code generation, though there are limitations when [using a mixed targetframeworks graph](https://github.com/dotnet/roslyn/issues/23114), such as generating code\nin a `net47` project that references a `netstandard2.0` project. In such cases, prefer adding a `net47` target instead of targeting `netstandard2.0`.\n\nVisual Studio 2017 15.3+ for Windows, macOS and Linux builds are supported. Building for .NET Core requires .NET 3.0.100 or later.\n\n## Build status\n\n| Target | Branch | Status |\n| ------ | ------ | ------ |\n| development | master |[![Build Status](https://dev.azure.com/uno-platform/Uno%20Platform/_apis/build/status/Uno%20Platform/Uno.SourceGeneration%20CI?branchName=master)](https://dev.azure.com/uno-platform/Uno%20Platform/_build/latest?definitionId=32\u0026branchName=master)\n\n## Nuget Packages\n\n| Package | nuget.org | usage |\n| -- | -- | -- |\n| `Uno.SourceGeneration` | [![NuGet](https://img.shields.io/nuget/v/Uno.SourceGeneration.svg)](https://www.nuget.org/packages/Uno.SourceGeneration/) | Use this package to create a generator |\n| `Uno.SourceGenerationTasks` | [![NuGet](https://img.shields.io/nuget/v/Uno.SourceGenerationTasks.svg)](https://www.nuget.org/packages/Uno.SourceGenerationTasks/) | Use this package to use a generator |\n\nExperimental packages are available through this NuGet feed: https://pkgs.dev.azure.com/uno-platform/Uno%20Platform/_packaging/unoplatformdev/nuget/v3/index.json\n\n## Creating a Source Generator\n\n1. In Visual Studio 2017, create a **.NET Standard Class Library** project named `MyGenerator`\n2. In the csproj file\n    1. Change the TargetFramework to `net46`\n    2. Add a package reference to `Uno.SourceGeneration` (take the latest version)\n    ```xml\n    \u003cItemGroup\u003e\n        \u003cPackageReference Include=\"Uno.SourceGeneration\" Version=\"1.5.0\" /\u003e\n    \u003c/ItemGroup\u003e\n    ```\n3. Add a new source file containing this code :\n    ```csharp\n    using System;\n    using Uno.SourceGeneration;\n\n    namespace MyGenerator\n    {\n        public class MyCustomSourceGenerator : SourceGenerator\n        {\n            public override void Execute(SourceGeneratorContext context)\n            {\n                var project = context.GetProjectInstance();\n\n                context.AddCompilationUnit(\"Test\", \"namespace MyGeneratedCode { class TestGeneration { } }\");\n            }\n        }\n    }\n    ```\n    Note that the GetProjectInstance is a helper method that provides access to the msbuild project currently being built. It provides access to the msbuild properties and item groups of the project, allowing for fine configuration of the source generator.\n\n4. Create a file named `MyGenerator.props` (should be the name of your project + `.props`) in a folder named\n   `build` and set its _Build Action_ to `Content`. Put the following content:\n    ```xml\n    \u003cProject\u003e\n        \u003cItemGroup\u003e\n            \u003cSourceGenerator Include=\"$(MSBuildThisFileDirectory)..\\bin\\$(Configuration)\\net46\\MyGenerator.dll\"\n                    Condition=\"Exists('$(MSBuildThisFileDirectory)..\\bin')\" /\u003e\n            \u003cSourceGenerator Include=\"$(MSBuildThisFileDirectory)..\\tools\\MyGenerator.dll\"\n                    Condition=\"Exists('$(MSBuildThisFileDirectory)..\\tools')\" /\u003e\n        \u003c/ItemGroup\u003e\n    \u003c/Project\u003e\n    ```\n\n## Using the generator inside the same solution (another project)\n\n1. In Visual Studio 2017, create a **.NET Standard Class Library** project named `MyLibrary`.\n   This is the project where your generator will do its generation.\n1. In the `.csproj` file:\n    1. Change the TargetFramework to `net46` (.Net Framework v4.6)\n    1. Add a package reference to `Uno.SourceGenerationTasks`\n    ```xml\n    \u003cItemGroup\u003e\n        \u003cPackageReference Include=\"Uno.SourceGenerationTasks\" Version=\"1.5.0\" /\u003e\n    \u003c/ItemGroup\u003e\n    ```\n    \u003e *You can also use the Nuget Package Manager to add this package reference.\n    \u003e **The version can differ, please use the same than the generator project**.\n    1. Import the source generator by placing the following line at the end :\n    ```xml\n    \u003cImport Project=\"..\\MyGenerator\\build\\MyGenerator.props\" /\u003e\n    ```\n1. Add some C# code that uses the `MyGeneratedCode.TestGeneration` class that the generator creates.\n1. Compile... it should works.\n1. You can sneak at the generated code by clicking the _Show All Files_ button in the _Solution Explorer_.\n   The code will be in the folder `obj\\\u003cconfig\u003e\\\u003cplatform\u003e\\g\\\u003cgenerator name\u003e\\`.\n\n## Packaging the source generator in NuGet\n\nPackaging the generator in nuget requires to :\n\n1. In the `csproj` file containing your generator:\n   1. Add this group to your csproj:\n    ```xml\n    \u003cItemGroup\u003e\n        \u003cContent Include=\"build/**/*.*\"\u003e\n        \u003cPack\u003etrue\u003c/Pack\u003e\n        \u003cPackagePath\u003ebuild\u003c/PackagePath\u003e\n        \u003c/Content\u003e\n    \u003c/ItemGroup\u003e\n\n    ```\n\n    Note that the name of this file must match the package name to be taken into account by nuget.\n\n    1. Update the package references as follows\n        ```xml\n        \u003cItemGroup\u003e\n            \u003cPackageReference Include=\"Uno.SourceGeneration\" Version=\"1.19.0-dev.316\" PrivateAssets=\"All\" /\u003e\n            \u003cPackageReference Include=\"Uno.SourceGenerationTasks\" Version=\"1.19.0-dev.316\" PrivateAssets=\"None\" /\u003e\n        \u003c/ItemGroup\u003e\n        ```\n        This ensure that the source generator tasks will be included in any project referencing your\n        new generator, and that the source generation interfaces are not included.\n\n        \u003e *You can also use the Nuget Package Manager to add this package reference.\n        \u003e **The version can differ, please take the latest stable one**.\n\n    1. Add the following property:\n        ```xml\n        \u003cPropertyGroup\u003e\n            \u003cIsTool\u003etrue\u003c/IsTool\u003e\n        \u003c/PropertyGroup\u003e\n        ```\n        This will allow for the generator package to be installed on any target framework.\n\n## Creating a C# 9.0 compatible generator\n\nBased on [C# 9.0 generators](https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.cookbook.md) the bootstrapper defines a set of APIs that are compatible with Roslyn.\n\nHere's a roslyn compatible generator:\n```csharp\n[Generator]\npublic class CustomGenerator : ISourceGenerator\n{\n    public void Initialize(GeneratorInitializationContext context) {}\n\n    public void Execute(GeneratorExecutionContext context)\n    {\n        context.AddSource(\"myGeneratedFile.cs\", @\"\nnamespace GeneratedNamespace\n{\n    public class GeneratedClass\n    {\n        public static void GeneratedMethod()\n        {\n            // generated code\n        }\n    }\n}\");\n    }\n}\n```\n\nUno also provides a set of methods giving access [to the MSBuild properties and items](https://github.com/dotnet/roslyn/blob/master/docs/features/source-generators.cookbook.md#consume-msbuild-properties-and-metadata), compatible Uno's source generation tasks:\n```csharp\npublic void Execute(GeneratorExecutionContext context)\n{\n\tvar myProperty = context.GetMSBuildPropertyValue(\"MyTestProperty\");\n\n    var myItems = context.GetMSBuildPropertyValue(\"GetMSBuildItems\").Select(i =\u003e i.Identity);\n}\n```\n\nNote that the a generator running under Uno.SourceGenerationTasks does not need to define in MSBuild which properties need to be used, whereas C# 9.0 requires it.\n\n## Debugging a generator\n\nIn your generator, add the following in the `SourceGenerator.Execute` override :\n\n```csharp\nDebugger.Launch();\n```\n\nThis will open another visual studio instance, and allow for stepping through the generator's code.\n\n## General guidelines for creating generators\n\n* Generators should have the least possible external dependencies.\n  Generators are loaded in a separate `AppDomain` but multiple assemblies versions can be\n  troublesome when loaded side by side.\n\n* You can add a dependency on your generator by adding the `Uno.SourceGeneration.SourceGeneratorDependency`\n  attribute on your class:\n\n  ```csharp\n  [GenerateAfter(\"Uno.ImmutableGenerator\")] // Generate ImmutableGenerator before EqualityGenerator\n  public class EqualityGenerator : SourceGenerator\n  ```\n\n  For instance here, it will ensure that the `ImmutableGenerator` is executed before your `EqualityGenerator`.\n  If you don't declare those dependencies, when a project is loaded to be analyzed, all generated files\n  from a generator are excluded from the roslyn `Compilation` object of other generators, meaning that if\n  two generators use the same conditions to generate the same code, there will be a compilation\n  error in the resulting code.\n\n* You can also define a generator which must be executed **after** yours. To do this, you need to declare a\n  _dependent generator_:\n\n  ```csharp\n  [GenerateBefore(\"Uno.EqualityGenerator\")] // Generate ImmutableGenerator before EqualityGenerator\n  public class ImmutableGenerator : SourceGenerator\n  ```\n\n* Sometimes you may need to kill all instances of MsBuild. On Windows, the fatest way to to that\n  is to open a shell in admin mode and type this line:\n\n  ``` powershell\n  taskkill /fi \"imagename eq msbuild.exe\" /f /t\n  ```\n\n## Logging to build output\n\nYou can write to build output using the following code:\n\n``` csharp\n    public override void Execute(SourceGeneratorContext context)\n    {\n        var logger = context.GetLogger(); // this is an extension method on SourceGeneratorContext\n\n        // Log something to build output when the mode is \"detailed\".\n        logger.Debug($\"The current count is {count}\");\n\n        // Log something to build output when the mode is \"normal\".\n        logger.Info($\"A total of {filesCount} has been generated.\");\n\n        // Log something as warning in build output.\n        logger.Warn($\"No code generated because the mode is {currentMode}.\");\n\n        // Log something as error in build output.\n        logger.Error($\"Unable to open file {filename}. No code generated.\");\n    }\n```\n\n## Available Properties\n\nThe source generation task provides set of properties that can alter its behavior based on your project.\n\n### UnoSourceGeneratorAdditionalProperty\n\nThe `UnoSourceGeneratorAdditionalProperty` item group provides the ability for a project to enable the\npropagation of specific properties to the generators. This may be required if properties are \n[injected dynamically](https://github.com/Microsoft/VSProjectSystem/blob/master/doc/extensibility/IProjectGlobalPropertiesProvider.md#iprojectglobalpropertiesprovider),\nor provided as global variables.\n\nA good example of this is the `JavaSdkDirectory` that is generally injected as a global parameter through\nthe msbuild command line.\n\nIn such as case, add the following in your project file:\n\n```xml\n\u003cItemGroup\u003e\n    \u003cUnoSourceGeneratorAdditionalProperty Include=\"JavaSdkDirectory\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\nIn this case, the `JavaSdkDirectory` value will be captured in the original build environment, and provided\nto the generators' build environment.\n\n## Troubleshooting\n\n### Error: `Failed to analyze project file ..., the targets ... failed to execute.`\n\nThis is issue is caused by a [open Roslyn issue](https://github.com/nventive/Uno.SourceGeneration/issues/2)\nfor which all projects of the solution must have all the possible \"head\" projects configuration.\n\nFor instance, if you are building a UWP application, all the projects in the solution must\nhave the `10.0.xxx` target framework defined, even if `netstandard2.0` would have been enough.\n\n### Generation output\n\nThe source generator provides additional details when building, when running the `_UnoSourceGenerator` msbuild target.\n\nTo view this information either place visual studio in `details` verbosity (**Options**, **Projects and Solutions**,\n**Build and Run** then **MSBuild project build output verbosity**) or by using the excellent\n[MSBuild Binary and Structured Log Viewer](http://msbuildlog.com/) from [Kirill Osenkov](https://twitter.com/KirillOsenkov).\n\nThe source generation target can also optionally produces `binlog` file in the obj folder, used to troubleshoot issues with the msbuild instance\ncreated inside the application domain used to generate the code. The path for those files can be altered using the\n`UnoSourceGeneratorBinLogOutputPath` msbuild property. In the context of a VSTS build, setting it to `$(build.artifactstagingdirectory)`\nallows for an improved diagnostics experience. Set the `UnoSourceGeneratorUnsecureBinLogEnabled` property to true to enabled binary logging.\n\n\u003e **Important**: The binary logger may leak secret environment variables, it is a best practice to never enable this feature as part of normal build.\n\n### My build ends with error code 3\n\nBy default, in some cases, the source generation host will run into an internal error, and will exit without providing details about the generation error.\n\nTo enable the logging of these errors, add the following property to your project:\n```xml\n\u003cUnoSourceGeneratorCaptureGenerationHostOutput\u003etrue\u003c/UnoSourceGeneratorCaptureGenerationHostOutput\u003e\n```\n\nThe errors will the be visible when the build logging output is set to detailed, or by [using the binary logger](https://github.com/Microsoft/msbuild/blob/master/documentation/wiki/Binary-Log.md).\n\n# Have questions? Feature requests? Issues?\n\nMake sure to visit our [StackOverflow](https://stackoverflow.com/questions/tagged/uno-platform), [create an issue](https://github.com/nventive/Uno.SourceGeneration/issues) or [visit our gitter](https://gitter.im/uno-platform/Lobby).\n\n\n## Upgrade notes\n\n### earlier versions to 1.29\nA breaking change has been introduced to support proper UWP head projects, and when upgrading to Uno.SourceGenerationTasks `1.29` or later\nyou will have to search for projects that contain the `uap10.0` target framework and do the following:\n- Update to the MSBuild.Sdk.Extras 1.6.65 or later\n- Choose an UWP sdk version, and use the appropriate target framework (e.g. `uap10.0` to `uap10.0.16299`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funoplatform%2Funo.sourcegeneration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funoplatform%2Funo.sourcegeneration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funoplatform%2Funo.sourcegeneration/lists"}